经典题目6

poj   3070   Fibonacci

题目链接:http://poj.org/problem?id=3070

给定n和p,求第n个Fibonacci数mod p的值,n不超过2^31
根据前面的 一些思路,现在我们需要构造一个2 x 2的矩阵,使得它乘以(a,b)得到的结果是(b,a+b)。每多乘一次这个矩阵,这两个数就会多迭代一次。那么,我们把这个2 x 2的矩阵自乘n次,再乘以(0,1)就可以得到第n个Fibonacci数了。不用多想,这个2 x 2的矩阵很容易构造出来:

矩阵十题(6)

代码如下:

 1 #include<stdio.h>
 2 #include<string.h>
 3 #define N 10
 4 struct Matrix
 5 {
 6     int a[N][N];
 7 }origin,res,tmp,ans;
 8 int n,m;
 9 Matrix mul(Matrix x,Matrix y)
10 {
11     int i,j,k;
12     memset(tmp.a,0,sizeof(tmp.a));
13     for(i=1;i<=n;i++)
14         for(j=1;j<=n;j++)
15             for(k=1;k<=n;k++)
16             {
17                 tmp.a[i][j]+=(x.a[i][k]*y.a[k][j])%m;
18                 tmp.a[i][j]%=m;
19             }
20     return tmp;
21 }
22 void quickpow(int k)  //矩阵快速幂
23 {
24     int i;
25     memset(res.a,0,sizeof(res.a));
26     for(i=1;i<=n;i++)
27         res.a[i][i]=1;
28     while(k)
29     {
30         if(k&1)
31             res=mul(res,origin);
32         origin=mul(origin,origin);
33         k>>=1;
34     }
35 }
36 int main()
37 {
38     int k;
39     n=2;
40     m=10000;
41     while(scanf("%d",&k)&&k!=-1)
42     {
43         origin.a[1][1]=0;  //初始化矩阵A
44         origin.a[1][2]=1;
45         origin.a[2][1]=1;
46         origin.a[2][2]=1;
47         quickpow(k);
48         memset(tmp.a,0,sizeof(tmp.a));   //相当于| 0 |
49         tmp.a[2][1]=1;                   //      | 1 |
50         ans=mul(res,tmp);   
51     /*    for(int i=1;i<=n;i++)
52         {
53             for(int j=1;j<=n;j++)
54                 printf("%d ",res.a[i][j]);
55             printf("\n");
56         }*/
57         printf("%d\n",ans.a[1][1]%m);
58     }
59     return 0;
60 }
View Code

相关文章: