hdu 4549 M斐波那契数列

http://acm.hdu.edu.cn/showproblem.php?pid=4549

思路:

观察a,b的幂符合斐波那契数列,因为n特别的大,所以构造矩阵求出a,b的第n的幂。 构造矩阵之后矩阵快速幂,因为在快速幂的时候矩阵相乘会超出__int64。所以需要用到一个定理

当gcd(a,mod)==1的时候  
a^x = a^( x mod Eular(mod) ) ( mod mod ) . 所以变成这样a^b%mod=a^(b%(mod-1))%mod; 

 1 #include <cstdio>
 2 #include<cstring>
 3 #include <algorithm>
 4 #define LL __int64
 5 using namespace std;
 6 const int mod=1e9+7;
 7 
 8 LL a,b,n;
 9 
10 struct node
11 {
12     LL a[4][4];
13 };
14 
15 node mul(node x,node y)
16 {
17     node c;
18     for(int i=0; i<2; i++)
19     {
20         for(int j=0; j<2; j++)
21         {
22             c.a[i][j]=0;
23             for(int k=0; k<2; k++)
24             {
25                 c.a[i][j]+=x.a[i][k]*y.a[k][j];
26                 c.a[i][j]%=(mod-1);
27             }
28         }
29     }
30     return c;
31 }
32 
33 node pow_m(node c,int n)
34 {
35     node temp;
36     memset(temp.a,0,sizeof(temp.a));
37     temp.a[0][0]=1; temp.a[1][1]=1;
38     node xx=c;
39     while(n)
40     {
41         if(n&1) temp=mul(temp,xx);
42         xx=mul(xx,xx);
43         n>>=1;
44     }
45     return temp;
46 }
47 
48 LL pow_M(LL a,LL n)
49 {
50     LL ans=1;
51     LL temp=a%mod;
52     while(n)
53     {
54         if(n&1)
55         {
56             ans*=temp;
57             ans%=mod;
58         }
59         temp*=temp;
60         temp%=mod;
61         n>>=1;
62     }
63     return ans;
64 }
65 
66 int main()
67 {
68     node tem;
69     tem.a[0][0]=0; tem.a[0][1]=1;
70     tem.a[1][0]=tem.a[1][1]=1;
71     while(scanf("%I64d%I64d%I64d",&a,&b,&n)!=EOF)
72     {
73         node st=pow_m(tem,n);
74         printf("%I64d\n",(pow_M(a,st.a[0][0])*pow_M(b,st.a[1][0]))%mod);
75     }
76     return 0;
77 }
View Code

 

posted @ 2014-11-19 20:47  null1019  阅读(155)  评论(0编辑  收藏  举报