[洛谷P1349]廣義斐波那契數列
阿新 • • 發佈:2017-10-06
矩陣加速 解題思路 string 簡單 set c++ mat 題目 n-1
題目大意:設$f[n]=f[n-1]*p+f[n-2]*q(當n>2時)$,給你p,q,f[1],f[2],n,m,求f[n]mod m的值。
解題思路:明顯,遞推是會TLE的,我們又得用矩陣加速大法了。
於是就很簡單了。
$$\begin{bmatrix}f[n-1]\\f[n]\end{bmatrix}\quad=\begin{bmatrix}0&1\\q&p\end{bmatrix}^{n-2}\quad ×\begin{bmatrix}f[0]\\f[1]\end{bmatrix}\quad$$
時間復雜度$O(\log_2 n)$
C++ Code:
#include<cstdio> #include<cstring> using namespace std; int P,Q,a1,a2,n,m; struct mat{ long long a[30][30]; int r,c; }; mat mul(mat x,mat y){ mat ans; memset(&ans,0,sizeof ans); for(int i=0;i<x.r;++i) for(int j=0;j<y.c;++j) for(int k=0;k<x.c;++k) ans.a[i][j]=(ans.a[i][j]+x.a[i][k]*y.a[k][j])%m; ans.r=x.r; ans.c=y.c; return ans; } void pow(int n){ mat p; memset(&p,0,sizeof p); p.r=p.c=2; p.a[0][1]=1; p.a[1][0]=Q; p.a[1][1]=P; mat ans; memset(&ans,0,sizeof ans); ans.r=ans.c=2; ans.a[0][0]=ans.a[1][1]=1; while(n){ if(n&1){ ans=mul(p,ans); } p=mul(p,p); n>>=1; } p.a[0][0]=a1%m; p.a[1][0]=a2%m; p.c=1; ans=mul(ans,p); printf("%d\n",(int)ans.a[1][0]); } int main(){ scanf("%d%d%d%d%d%d",&P,&Q,&a1,&a2,&n,&m); if(n==1)printf("%d\n",a1%m);else if(n==2)printf("%d\n",a2%m);else pow(n-2); return 0; }
[洛谷P1349]廣義斐波那契數列