hdu--4549 M斐波那契数列

Problem Description
M斐波那契数列F[n]是一种整数数列,它的定义如下:

F[0] = a
F[1] = b
F[n] = F[n-1] * F[n-2] ( n > 1 )

现在给出a, b, n,你能求出F[n]的值吗?
 

 

Input
输入包含多组测试数据;
每组数据占一行,包含3个整数a, b, n( 0 <= a, b, n <= 10^9 )
 

 

Output
对每组测试数据请输出一个整数F[n],由于F[n]可能很大,你只需输出F[n]对1000000007取模后的值即可,每组数据输出一行。
 

 

Sample Input
0 1 0 6 10 2
 

 

Sample Output
0 60
 

 

Source
中文题
思路:利用矩阵快速幂求出斐波那契数列,由费马小定理知: a^f(n-1) = a^(f(n-1)%1000000006) (mod 1000000007),b^f(n) = b^(f(n)%1000000006) (mod 1000000007),使用快速幂既能求得结果。
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <queue>
 6 using namespace std;
 7 const long long  SMod=1000000006;
 8 const long long Smod=1000000007;
 9 struct Matrix
10 {
11     long long m[7][7];
12 };
13 Matrix Mul(Matrix a,Matrix b)
14 {
15     Matrix c;
16     memset(c.m,0,sizeof(c.m));
17     for(int i=0; i<2; i++)
18         for(int j=0; j<2; j++)
19             for(int k=0; k<2; k++)
20                 c.m[i][j]+=((a.m[i][k]*b.m[k][j])%SMod+SMod)%SMod;
21     return c;
22 }
23 Matrix fastm(Matrix a,int n)
24 {
25     Matrix res;
26     memset(res.m,0,sizeof(res.m));
27     for(int i=0; i<2; i++)
28         res.m[i][i]=1;
29     while(n)
30     {
31         if(n&1)
32             res=Mul(res,a);
33         n>>=1;
34         a=Mul(a,a);
35     }
36     return res;
37 }
38 int main()
39 {
40     Matrix a;
41     int x,y,n;
42     while(~scanf("%d%d%d",&x,&y,&n))
43     {
44         if(n<2)
45         {
46             if(n==0)
47                 printf("%d\n",x);
48             else
49                 printf("%d\n",y);
50             continue;
51         }
52         memset(a.m,0,sizeof(a.m));
53         a.m[0][0]=a.m[0][1]=a.m[1][0]=1;
54         a=fastm(a,n-1);
55         long long k=a.m[0][0],tmp=y;
56         long long ans=1;
57         while(k)
58         {
59             if(k&1)
60             ans=(ans*tmp)%Smod;
61             k>>=1;
62             tmp=(tmp*tmp)%Smod;
63         }
64         k=a.m[1][0];
65         tmp=x;
66         while(k)
67         {
68             if(k&1)
69                 ans=(ans*tmp)%Smod;
70             k>>=1;
71             tmp=(tmp*tmp)%Smod;
72         }
73         printf("%lld\n",ans%Smod);
74     }
75     return 0;
76 }
View Code

 

posted @ 2017-03-06 20:22  Wally的博客  阅读(182)  评论(0编辑  收藏  举报