Another kind of Fibonacci
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1200 Accepted Submission(s): 454
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 <= 2 31 – 1
X : 2<= X <= 2 31– 1
Y : 2<= Y <= 2 31 – 1
Each test case will contain three integers , N, X , Y .
N : 2<= N <= 2 31 – 1
X : 2<= X <= 2 31– 1
Y : 2<= Y <= 2 31 – 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这是一个变形的科波菲尔数列问题,重点是自己构造一个矩阵Matrix P = { 1,1,0,0, 0,x^2,y^2,2xy, 0,1,0,0, 0,x,0,y };Matrix Q= { s(n-1) A(n-1)^2 A(n-2)^2 A(n-1)A(n-2) }; Matrix W= { s(n) A(n)^2 A(n-1)^2 A(n)A(n-1) };自然P*Q=W#include <cstdlib> #include <cstring> #include <cstdio> #include <iostream> using namespace std; //N表示矩阵的N次幂 int N; int nn,xx,yy; const int mod= 10007 ; //此处假设矩阵为3*3阶 //origin存放需计算的矩阵,res存放答案矩阵 struct matrix { int a[4][4]; }origin,res; //直接将2个矩阵相乘x*y,返回计算后的矩阵 matrix multiply(matrix x,matrix y) { matrix temp; memset(temp.a,0,sizeof(temp.a)); for(int i=0;i<4;i++) { for(int j=0;j<4;j++) { for(int k=0;k<4;k++) { temp.a[i][j]=(temp.a[i][j]+x.a[i][k]*y.a[k][j])%mod; } } } return temp; } //将res初始化为单位矩阵,人为输入origin void init() { memset(origin.a,0,sizeof(origin)); xx=xx%mod; yy=yy%mod; origin.a[0][0]=origin.a[0][1]=1; origin.a[1][1]=(xx*xx)%mod; origin.a[1][2]=(yy*yy)%mod; origin.a[1][3]=(2*xx*yy)%mod; origin.a[2][1]=1; origin.a[3][1]=xx; origin.a[3][3]=yy; //将res.a初始化为单位矩阵 memset(res.a,0,sizeof(res.a)); res.a[0][0]=res.a[1][1]=res.a[2][2]=res.a[3][3]=1; } //矩阵快速幂的计算 void calc(int n) { while(n) { if(n&1) res=multiply(res,origin); n>>=1; origin=multiply(origin,origin); } } int main() { while(~scanf("%d%d%d",&nn,&xx,&yy)) { init(); calc(nn); int ans=(res.a[0][0]%mod+res.a[0][1]%mod+res.a[0][2]%mod+res.a[0][3]%mod)%mod; printf("%d\n",ans); } return 0; }