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 <= 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
 

 

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 <= 2 31– 1
Y : 2<= Y <= 2 31 – 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 }

 

你可能感兴趣的:(fibonacci)