HDU 3306 Another kind of Fibonacci ---构造矩阵***

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
 

 

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
注意相乘时的溢出。
 
 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\n",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 }

 

posted @ 2013-08-19 18:20  芷水  阅读(167)  评论(0编辑  收藏  举报