1. 程式人生 > >[洛谷P1349] 廣義斐波那契數列

[洛谷P1349] 廣義斐波那契數列

tdi 裸題 == pre lin () long pan targe

復習矩陣乘法。

題目傳送門

裸題、水題。

a[n] a[n-1] * p 1 = a[n+1] a[n]

q 0

做這道題主要是因為自己突發奇想,嘗試用數列的特征根求出通項公式......

然後發現這個坑填不平了......

乖乖的改用矩乘秒掉了。

 1 #include<cstdio>
 2 #define ll long long
 3 
 4 ll p,q,a1,a2,n,m;
 5 
 6 struct matrix
 7 {
 8     ll a[2][2];
 9 }x;
10 11 ll mul(ll w,ll e) 12 { 13 ll ret=0; 14 while(e) 15 { 16 if(e&1)ret=(ret+w)%m; 17 w=(w+w)%m; 18 e>>=1; 19 } 20 return ret; 21 } 22 23 matrix mul(matrix w,matrix e) 24 { 25 matrix ret; 26 for(int i=0;i<=1;i++) 27 { 28 for
(int j=0;j<=1;j++) 29 { 30 ret.a[i][j]=0; 31 for(int k=0;k<=1;k++) 32 { 33 ret.a[i][j]=(ret.a[i][j]+mul(w.a[i][k],e.a[k][j]))%m; 34 } 35 } 36 } 37 return ret; 38 } 39 40 matrix ksm(matrix w,ll e) 41 { 42 matrix ret=w;
43 e--; 44 while(e) 45 { 46 if(e&1)ret=mul(ret,w); 47 w=mul(w,w); 48 e>>=1; 49 } 50 return ret; 51 } 52 53 int main() 54 { 55 scanf("%lld%lld%lld%lld%lld%lld",&p,&q,&a1,&a2,&n,&m); 56 x.a[0][0]=p; 57 x.a[0][1]=1; 58 x.a[1][0]=q; 59 x.a[1][1]=0; 60 if(n==1)printf("%lld",a1); 61 else 62 { 63 x=ksm(x,n-1); 64 printf("%lld",(x.a[0][1]*a2%m+x.a[1][1]*a1%m)%m); 65 } 66 return 0; 67 }

[洛谷P1349] 廣義斐波那契數列