矩阵快速幂
例题(简单):
http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Index/problemdetail/pid/1132.html
代码:
#include<iostream>
#include<string>
#include<cstring>
#include<queue>
#include<stdio.h>
#include<stack>
#include<map>
#include<stack>
using namespace std;
# define maxn 100
# define ll long long
struct Matrix
{
int a[maxn][maxn];
Matrix operator *( Matrix b)
{
Matrix temp;
for(int i=1; i<=2; i++)
{
for(int j=1; j<=2; j++)
{
temp.a[i][j]=0;
for(int k=1; k<=2; k++)
{
temp.a[i][j]+=a[i][k]*b.a[k][j];
}
}
}
return temp;
}
} a;
Matrix quickpow(Matrix t,int w)
{
Matrix temp=t;
w--;
while(w)
{
if(w&1)
{
temp=temp*t;
}
w>>=1;
t=t*t;
}
return temp;
}
int main()
{
int n;
cin>>n;
Matrix t;
t.a[1][1]=1;
t.a[1][2]=1;
t.a[2][1]=1;
t.a[2][2]=0;//初始矩阵
if(n==1)
cout<<1<<endl;
else if(n==2)
cout<<1<<endl;
else
{
t=quickpow(t,n-2);
int temp=t.a[1][1]+t.a[2][1];
cout<<temp<<endl;
}
return 0;
}
例题(较难):
题目链接:https://vjudge.net/problem/HDU-5950
AC代码:
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<stdio.h>
using namespace std;
# define inf 0x3f3f3f3f
# define ll long long
# define mod 2147493647
struct Matrix
{
ll t[10][10];
Matrix operator *(Matrix a)
{
Matrix temp;
for(int i=0; i<7; i++)
{
for(int j=0; j<7; j++)
{
temp.t[i][j]=0;
for(int k=0; k<7; k++)
{
temp.t[i][j]+=a.t[i][k]*t[k][j];
temp.t[i][j]%=mod;
}
}
}
return temp;
}
};
Matrix quickpow(Matrix t1, ll t2)
{
Matrix s;
s=t1;
t2--;
while(t2)
{
if(t2&1)s=s*t1;
t2>>=1;
t1=t1*t1;
}
return s;
}
ll n,a,b;
int main()
{
ll T;
scanf("%lld",&T);
while(T--)
{
Matrix w;
w.t[0][0]=1;
w.t[0][1]=1;
w.t[0][2]=0;
w.t[0][3]=0;
w.t[0][4]=0;
w.t[0][5]=0;
w.t[0][6]=0;
w.t[1][0]=2;
w.t[1][1]=0;
w.t[1][2]=0;
w.t[1][3]=0;
w.t[1][4]=0;
w.t[1][5]=0;
w.t[1][6]=0;
w.t[2][0]=1;
w.t[2][1]=0;
w.t[2][2]=1;
w.t[2][3]=0;
w.t[2][4]=0;
w.t[2][5]=0;
w.t[2][6]=0;
w.t[3][0]=4;
w.t[3][1]=0;
w.t[3][2]=4;
w.t[3][3]=1;
w.t[3][4]=0;
w.t[3][5]=0;
w.t[3][6]=0;
w.t[4][0]=6;
w.t[4][1]=0;
w.t[4][2]=6;
w.t[4][3]=3;
w.t[4][4]=1;
w.t[4][5]=0;
w.t[4][6]=0;
w.t[5][0]=4;
w.t[5][1]=0;
w.t[5][2]=4;
w.t[5][3]=3;
w.t[5][4]=2;
w.t[5][5]=1;
w.t[5][6]=0;
w.t[6][0]=1;
w.t[6][1]=0;
w.t[6][2]=1;
w.t[6][3]=1;
w.t[6][4]=1;
w.t[6][5]=1;
w.t[6][6]=1;
scanf("%lld%lld%lld",&n,&a,&b);
if(n==1)printf("%lld\n",a);
else if(n==2)printf("%lld\n",b);
else if(n>2)
{
Matrix ans=quickpow(w,n-2);
ll num=0;
num+=b*ans.t[0][0];
num%=mod;
num+=a*ans.t[1][0];
num%=mod;
num+=16*ans.t[2][0];
num%=mod;
num+=8*ans.t[3][0];
num%=mod;
num+=4*ans.t[4][0];
num%=mod;
num+=2*ans.t[5][0];
num%=mod;
num+=ans.t[6][0];
num%=mod;
printf("%lld\n",num);
}
}
return 0;
}