这三道算是矩阵快速幂的入门题了。。
1.POJ3070 Fibonacci sequence
先贴大佬博客:https://blog.csdn.net/ccf15068475758/article/details/52846726
初始化:n=1时,F0=0,F1=1,F2=1。可以发现和A矩阵相同,合并为A^n
又因为要输出最后四位数,MOD=10000
附上AC代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
#define ll long long
const int MOD=10000;
ll n;
typedef struct
{
ll a[2][2];
}mat;
mat c,res;
mat mul(mat x,mat y,int n)
{
mat cnt;
memset(cnt.a,0,sizeof(cnt.a));
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
cnt.a[i][j]+=x.a[i][k]*y.a[k][j]%MOD;
return cnt;
}
void pow()
{
c.a[0][0]=c.a[0][1]=c.a[1][0]=1;
c.a[1][1]=0;
memset(res.a,0,sizeof(res.a));
res.a[0][0]=res.a[1][1]=1;
n--;
while(n>0)
{
if(n&1)
res=mul(res,c,2);
c=mul(c,c,2);
n=(n>>1);
}
}
int main()
{
while(cin>>n)
{
if(n==-1)
break;
else if(n==0)
cout<<"0"<<endl;
else
{
pow();
cout<<res.a[0][0]%MOD<<endl;
}
}
return 0;
}
2.HDU1005 Number Sequence
同样先附上博客:https://blog.csdn.net/oranges_c/article/details/55224528
其实递推式不一定全是2*2的矩阵,可以2*1=[2*2]*[2*1]这种的,主要是中间的A^n用到矩阵快速幂,A为方阵。剩下的利用矩阵知识求解就行,比如F(n)=A^(n-2)的第一行*初始化第一列%MOD。
附上AC代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
#define ll long long
#define pi acos(-1.0)
const int MOD=7;
ll a,b,n;
typedef struct
{
ll a[2][2];
}mat;
mat c,res;
mat mul(mat x,mat y,int n)
{
mat cnt;
memset(cnt.a,0,sizeof(cnt.a));
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
cnt.a[i][j]+=x.a[i][k]*y.a[k][j]%MOD;
return cnt;
}
void pow()
{
c.a[0][0]=a;
c.a[0][1]=b;
c.a[1][0]=1;
c.a[1][1]=0;
memset(res.a,0,sizeof(res.a));
res.a[0][0]=res.a[1][1]=1;
n-=2;
while(n>0)
{
if(n&1)
res=mul(res,c,2);
c=mul(c,c,2);
n=(n>>1);
}
}
int main()
{
while(cin>>a>>b>>n)
{
if(a==0&&b==0&&n==0)
break;
pow();
cout<<(res.a[0][0]+res.a[0][1])%MOD<<endl;
}
return 0;
}
3.HDU1575 Tr A
这道题也没什么特别的,就是矩阵大小变了,注意mul中n指矩阵大小,要更新。
附上AC代码:(直接作为板子了2333)
//n指矩阵大小,即a的行/列数;k指幂次
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
#define ll long long
#define pi acos(-1.0)
const int MOD=9973;//注意随题意变化
ll n,k;
typedef struct
{
ll a[12][12];
}mat;
mat c,res;
mat mul(mat x,mat y,int n)//注意x,y的顺序!一般AB≠BA!!
{
mat cnt;
memset(cnt.a,0,sizeof(cnt.a));
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
cnt.a[i][j]+=x.a[i][k]*y.a[k][j]%MOD;
return cnt;
}
void pow()
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&c.a[i][j]);
//res通常初始化为单位矩阵
memset(res.a,0,sizeof(res.a));
for(int i=0;i<n;i++)//注意此处循环不能少!
res.a[i][i]=1;
while(k>0)
{
if(k&1)
res=mul(res,c,n);
c=mul(c,c,n);
k=(k>>1);
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&k);
pow();
ll ans=0;
for(int i=0;i<n;i++)//求迹
ans+=res.a[i][i]%MOD;
cout<<ans%MOD<<endl;
}
return 0;
}