bzoj 3231 [Sdoi2008]递归数列——矩阵乘法
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3231
矩阵乘法裸题。
1018是10^18。别忘了开long long。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const int N=20; int n; ll L,R,b[N],c[N],mod,s[N],prn; struct Matrix{ ll a[N][N]; Matrix(){memset(a,0,sizeof a);} void init() { for(int i=1;i<n;i++)a[i][1]=c[i]; for(int i=2;i<n;i++)a[i-1][i]=1; a[1][n]=a[n][n]=1; } Matrix operator* (const Matrix &b)const { Matrix c; for(int i=1;i<=n;i++) for(int k=1;k<=n;k++) for(int j=1;j<=n;j++) (c.a[i][j]+=a[i][k]*b.a[k][j])%=mod; return c; } }ans,r,yans,yr; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%lld",&b[i]); s[i]=s[i-1]+b[i]; ans.a[1][n-i+1]=b[i]; } ans.a[1][n+1]=s[n-1]; yans=ans; for(int i=1;i<=n;i++)scanf("%lld",&c[i]); scanf("%lld%lld%lld",&L,&R,&mod); n++;r.init();yr=r; if(R<n)prn=s[R]; else { ll k=R-n+1; while(k) { if(k&1)ans=ans*r; r=r*r;k>>=1ll; } prn=(ans.a[1][n]+ans.a[1][1])%mod; } if(L-1<n)prn=((prn-s[L-1])%mod+mod)%mod; else { ll k=L-1-n+1; while(k) { if(k&1)yans=yans*yr; yr=yr*yr;k>>=1ll; } prn=((prn-yans.a[1][n]-yans.a[1][1])%mod+mod)%mod; } printf("%lld\n",prn); return 0; }