矩阵乘法加速线性递推的典型
大概套路就是先构造一个矩阵( F )使得另一初始矩阵( A )乘以( F^{x} )能够得出第n项
跑的飞快
虽然我也不知道那个矩阵要怎么构造
或许就像我使用了瞪眼法和枚举法
#include <cstdio> #include <algorithm> #include <cstring> #define int long long using namespace std; const int MOD = 1000000007; int n; struct Matrix{ static const int MAXN = 100; int alpha[MAXN][MAXN]; int n,m; void init(void){ for(int i=0;i<MAXN;i++) for(int j=0;j<MAXN;j++) alpha[i][j]=0; n=m=0; } void init_f2(void){ n=2;m=2; alpha[1][1]=1; alpha[2][1]=1; alpha[1][2]=1; alpha[2][2]=0; } void init_f(void){ n=1;m=2; alpha[1][1]=1; alpha[1][2]=1; } void init_pow(int x){ for(int i=1;i<=x;i++) alpha[i][i]=1; m=n=x; } Matrix operator * (Matrix b){ Matrix c; c.init(); for(int i=1;i<=n;i++) for(int j=1;j<=b.m;j++) for(int k=1;k<=m;k++) c.alpha[i][j]=(c.alpha[i][j]%MOD+alpha[i][k]*b.alpha[k][j]%MOD)%MOD; c.n=n; c.m=b.m; return c; } }; Matrix pow(Matrix a,int p){ Matrix ans; ans.init(); ans.init_pow(a.n); while(p){ if(p&1) ans=ans*a; a=a*a; p>>=1; } return ans; } signed main(){ scanf("%lld",&n); Matrix f,f2,ans; f.init(); f.init_f(); f2.init(); f2.init_f2(); ans=pow(f2,n-1); // for(int i=1;i<=ans.n;i++){ // for(int j=1;j<=ans.m;j++) // printf("%d ",ans.alpha[i][j]); // printf(" "); // } f=f*ans; printf("%lld",f.alpha[1][2]%MOD); return 0; }