题面:https://www.luogu.org/problem/P2461
拿到题面,矩阵快速幂裸题。
开始推矩阵。
推出的矩阵是这个样子:
右边是ans矩阵,左边是base矩阵。具体的可以看代码。
就可以开心的快速幂了!
但是由于求的是m到n之间的。
需要两次。
而且注意判断是不是小于K。
但是!!!最最最重要的!!!!!!!!!!
不要忘了统计答案时候!!!!!
(ans%p+p)%p
调了俩小时!!!!!!!!!!!!!!!!
代码如下:
#include<bits/stdc++.h> #define ll long long #define int long long using namespace std; int k,N,M,p; ll sum; int b[20],c[20]; struct node{ ll m[20][20]; }ans,base; inline node mul(node x,node y){ node res; memset(res.m,0,sizeof(res.m)); for(int i=1;i<=k+1;i++) for(int t=1;t<=k+1;t++){ if(!x.m[i][t]) continue; for(int j=1;j<=k+1;j++){ res.m[i][j]+=x.m[i][t]*y.m[t][j]; res.m[i][j]%=p; } } return res; } inline void qp(int t){ while(t){ if(t&1) ans=mul(ans,base); base=mul(base,base); t>>=1; } } signed main() { scanf("%lld",&k); for(int i=1;i<=k;i++) scanf("%lld",&b[i]); for(int i=1;i<=k;i++) scanf("%lld",&c[i]); scanf("%lld%lld%lld",&M,&N,&p); memset(ans.m,0,sizeof(ans.m));memset(base.m,0,sizeof(base.m)); for(int i=1;i<=k;i++) sum=(sum+b[i])%p; ans.m[1][1]=sum; for(int i=1;i<=k;i++) ans.m[1][i+1]=b[k-(i-1)]; base.m[1][1]=1; for(int i=2;i<=k;i++) base.m[i][i+1]=1; for(int i=2;i<=k+1;i++) base.m[i][1]=c[i-1],base.m[i][2]=c[i-1]; // for(int i=1;i<=k+1;i++){ // for(int j=1;j<=k+1;j++){ // cout<<base.m[i][j]<<" "; // } // puts(""); // } // for(int j=1;j<=k+1;j++) cout<<ans.m[1][j]<<endl; ll ans1=0; if((M-1)<k){ for(int i=1;i<=M-1;i++) ans1=(ans1+b[i])%p; }else{ qp(M-1-k); ans1=ans.m[1][1]%p; } memset(ans.m,0,sizeof(ans.m));memset(base.m,0,sizeof(base.m)); ans.m[1][1]=sum; for(int i=1;i<=k;i++) ans.m[1][i+1]=b[k-(i-1)]; base.m[1][1]=1; for(int i=2;i<=k;i++) base.m[i][i+1]=1; for(int i=2;i<=k+1;i++) base.m[i][1]=c[i-1],base.m[i][2]=c[i-1]; ll ans2=0; if(N<k){ for(int i=1;i<=N;i++) ans2=(ans2+b[i])%p; }else{ qp(N-k); ans2=ans.m[1][1]%p; } printf("%lld ",((ans2-ans1)%p+p)%p); //system("pause"); return 0; }