Another kind of Fibonacci
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1219 Accepted Submission(s): 466
Problem Description
As we all known , the Fibonacci series : F(0) = 1, F(1) = 1, F(N) = F(N - 1) + F(N - 2) (N >= 2).Now we define another kind of Fibonacci : A(0) = 1 , A(1) = 1 , A(N) = X * A(N - 1) + Y * A(N - 2) (N >= 2).And we want to Calculate S(N) , S(N) = A(0)2 +A(1)2+……+A(n)2.
Input
There are several test cases.
Each test case will contain three integers , N, X , Y .
N : 2<= N <= 231 – 1
X : 2<= X <= 231– 1
Y : 2<= Y <= 231 – 1
Each test case will contain three integers , N, X , Y .
N : 2<= N <= 231 – 1
X : 2<= X <= 231– 1
Y : 2<= Y <= 231 – 1
Output
For each test case , output the answer of S(n).If the answer is too big , divide it by 10007 and give me the reminder.
Sample Input
2 1 1
3 2 3
Sample Output
6
196
Author
wyb
同学说,矩阵这一块,最难到如何构造矩阵,这题是构造矩阵的经典例题。
如果构造的呢??
A(N)= X*A(N-1) + Y*A(N-2)
S(N)= S(N-1) + A(N)^2;
合并一下
S(N)= S(N-1) + X^2*A(N-1)^2 + Y^2*A(N-2) +2*X*Y*A(N-1)A(N-2);
很像做过到一道题目:HDU 1757 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);
那么把参数提取出来就有4个了:
S(N-1) A(N-1)^2 A(N-2)%^2 A(N-1)A(N-2)
对应到系数 1 X^2 Y^2 2*X*Y
| 1 X^2 Y^2 2*X*Y | | S(N-1) |
| 0 X^2 Y^2 2*X*Y | | A(N-1)^2 |
| 0 1 0 0 | | A(N-2)^2 |
| 0 X 0 Y | | A(N-1)A(N-2) |
自己推一推就可以的。
这一题还有一个地方需要注意:
X : 2<= X <= 231– 1
Y : 2<= Y <= 231 – 1
Y : 2<= Y <= 231 – 1
注意相乘时的溢出。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 using namespace std; 6 7 8 struct node 9 { 10 __int64 mat[6][6]; 11 }M_hxl,M_tom; 12 13 void make_init(__int64 x,__int64 y) 14 { 15 M_hxl.mat[1][1]=1; 16 M_hxl.mat[1][2]=(x*x)%10007; 17 M_hxl.mat[1][3]=(y*y)%10007; 18 M_hxl.mat[1][4]=(2*x*y)%10007; 19 20 M_hxl.mat[2][1]=0; 21 M_hxl.mat[2][2]=(x*x)%10007; 22 M_hxl.mat[2][3]=(y*y)%10007; 23 M_hxl.mat[2][4]=(2*x*y)%10007; 24 25 M_hxl.mat[3][1]=0; 26 M_hxl.mat[3][2]=1; 27 M_hxl.mat[3][3]=0; 28 M_hxl.mat[3][4]=0; 29 30 M_hxl.mat[4][1]=0; 31 M_hxl.mat[4][2]=x; 32 M_hxl.mat[4][3]=0; 33 M_hxl.mat[4][4]=y; 34 } 35 36 void make_first(node *cur) 37 { 38 __int64 i,j; 39 for(i=1;i<=4;i++) 40 for(j=1;j<=4;j++) 41 if(i==j) 42 cur->mat[i][j]=1; 43 else cur->mat[i][j]=0; 44 } 45 46 struct node cheng(node cur,node now) 47 { 48 node ww; 49 __int64 i,j,k; 50 memset(ww.mat,0,sizeof(ww.mat)); 51 for(i=1;i<=4;i++) 52 for(k=1;k<=4;k++) 53 if(cur.mat[i][k]) 54 { 55 for(j=1;j<=4;j++) 56 if(now.mat[k][j]) 57 { 58 ww.mat[i][j]+=cur.mat[i][k]*now.mat[k][j]; 59 if(ww.mat[i][j]>=10007) 60 ww.mat[i][j]%=10007; 61 } 62 } 63 return ww; 64 } 65 void power_sum2(__int64 n) 66 { 67 __int64 sum=0; 68 make_first(&M_tom); 69 while(n) 70 { 71 if(n&1) 72 { 73 M_tom=cheng(M_tom,M_hxl); 74 } 75 n=n>>1; 76 M_hxl=cheng(M_hxl,M_hxl); 77 } 78 sum=sum+2*M_tom.mat[1][1]+M_tom.mat[1][2]+M_tom.mat[1][3]+M_tom.mat[1][4]; 79 if(sum>=10007) 80 sum=sum%10007; 81 printf("%I64d ",sum); 82 83 } 84 85 86 int main() 87 { 88 __int64 n,x,y; 89 while(scanf("%I64d%I64d%I64d",&n,&x,&y)>0) 90 { 91 x=x%10007;//防止溢出 92 y=y%10007;//防止溢出 93 memset(M_hxl.mat,0,sizeof(M_hxl.mat)); 94 make_init(x,y); 95 power_sum2(n-1); 96 } 97 return 0; 98 }