矩阵有一个神奇的作用,它可以用来快速求递推式的第\(n\)项,学会这个技
具体怎么优化呢?
代码贴一发我写的模板
矩阵快速幂#include#include#include#include#define int long long #define mod 1000000007 using namespace std; const int maxn=1e2+10; int n,k; inline int read(){ int ret=0; int f=1; char ch=getchar(); while(ch'9'){ if(ch=='-') f=-f; ch=getchar(); } while(ch='0'){ ret=ret*10+(ch^'0'); ch=getchar(); } return f*ret; } struct mat{ int a[maxn][maxn]; mat(){ memset(a,0,sizeof(a)); } inline void build(){ for(int i=1;i<=n;i++){ a[i][i]=1; } } mat operator *(const mat &b){ mat ans; for(int k=1;k<=n;++k) for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) ans.a[i][j]=(((ans.a[i][j]%mod+a[i][k]*b.a[k][j]%mod)+mod)%mod); return ans; } void init(){ for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ a[i][j]=read(); } } void out(){ for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ cout<<a[i][j]<<" "; } cout<>1; } return ans; } signed main(){ // freopen("a.txt","r",stdin); n=read(); k=read(); mat a1; a1.init(); a1=pow(a1,k); a1.out(); return 0; }
矩阵加速
#include#include#include#include#define int long long #define mod 1000000007 using namespace std; const int maxn=1e2+10; inline int read(){ int ret=0; int f=1; char ch=getchar(); while(ch'9'){ if(ch=='-') f=-f; ch=getchar(); } while(ch='0'){ ret=ret*10+(ch^'0'); ch=getchar(); } return f*ret; } struct mat{ int a[4][4]; mat(){ memset(a,0,sizeof(a)); } void build(){ for(int i=1;i<=3;i++){ a[i][i]=1; } } mat operator *(const mat &b1){ mat ab; for(int k=1;k<=3;++k) for(int i=1;i<=3;++i) for(int j=1;j<=3;++j) ab.a[i][j]=(((ab.a[i][j]%mod+a[i][k]*b1.a[k][j]%mod)+mod)%mod); return ab; } void out(){ for(int i=1;i<=3;i++){ for(int j=1;j<=3;j++){ cout<<a[i][j]<<" "; } cout<<endl; } } }; int q[maxn]; int b[maxn]; int n; int an[maxn]; bool cmp(int x,int y){ return q[x]>1; } return ans; } mat mul(mat x,mat y){ mat ans; for(int k=1;k<=3;k++){ for(int i=1;i<=1;i++){ for(int j=1;j<=3;j++){ ans.a[i][j]=(ans.a[i][j]%mod+x.a[i][k]*y.a[k][j]%mod+mod)%mod; } } } return ans; } signed main(){ n=read(); for(int i=1;i<=n;i++){ q[i]=read(); b[i]=i; } sort(b+1,b+1+n,cmp); mat st; st.a[1][1]=1; st.a[1][2]=1; st.a[2][3]=1; st.a[3][1]=1; mat ans; ans.a[1][1]=1; ans.a[1][2]=1; ans.a[1][3]=1; int fla=0; for(int i=1;i<=n;i++){ if(q[b[i]]<=3){ an[b[i]]=1; continue; } if(fla==0){ ans=mul(ans,pow(st,q[b[i]]-3)); an[b[i]]=ans.a[1][1]; fla=1; continue; } ans=mul(ans,pow(st,q[b[i]]-q[b[i-1]])); an[b[i]]=ans.a[1][1]; } for(int i=1;i<=n;i++){ cout<<an[i]<<endl; } return 0; }
最后推荐一道练习题 P1306 斐波那契公约数