hdu4549_M斐波那契数列 解题报告

 

Solution:

1.快速幂:数/矩阵

2.以证明1000000007是素数。

费马小定理:

若p是素数,gcd(a,p)=1,则a^(p-1)1(mod p)。

若a^b mod p 中b很大,则可以简化为a^b mod p=a^[b mod (p-1)] mod p

证明如下:

b=t*(p-1)+r,其中r为b除以(p-1)的余数,即为b mod (p-1)。

a^b=(a^(p-1))^t * a^r  1^t * a^r  a^r (mod p)

费马小定理的推广:如果p为质数,xp-x(x是任意正整数)必能被p整除

 

注意是对b,对结果分别是取模(p-1),取模p;不要同时取模p或同时取模(p-1)!

 

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 #define yu_ 1000000006
 5 #define yu 1000000007
 6 
 7 int main()
 8 {
 9     //f[n]=a^x(n-1)*b^x(n)
10     //a^f(n-1) = a^(f(n-1)%1000000006) (mod 1000000007)
11     //1000000007 is a prime
12     long n,nn,w,i,c[2];
13     __int64 x[32],y[32],u[32],v[32],p,q,s,t,pp,qq,ss,tt,a,b,result;
14     x[0]=0;
15     y[0]=1;
16     u[0]=1;
17     v[0]=1;
18     for (i=1;i<32;i++)
19     {
20         x[i]=(x[i-1]*x[i-1]+y[i-1]*u[i-1])%yu_;
21         y[i]=(y[i-1]*(x[i-1]+v[i-1]))%yu_;
22         u[i]=(u[i-1]*(x[i-1]+v[i-1]))%yu_;
23         v[i]=(y[i-1]*u[i-1]+v[i-1]*v[i-1])%yu_;
24     }
25     while (scanf("%ld%ld%ld",&c[0],&c[1],&n)!=EOF)
26     {
27         if (n==0)
28         {
29             printf("%ld\n",c[0]);
30             continue;
31         }
32         else if (n==1)
33         {
34             printf("%ld\n",c[1]);
35             continue;
36         }
37         result=1;
38         for (i=0;i<2;i++)
39         {
40             p=1;
41             q=0;
42             s=0;
43             t=1;
44             //a:n-2 b:n-1
45             nn=n+i-2;
46             w=0;
47             while (nn)
48             {
49                 if ((nn & 1)==1)
50                 {
51                     pp=p;
52                     qq=q;
53                     ss=s;
54                     tt=t;
55                     p=(pp*x[w]+qq*u[w])%yu_;
56                     q=(pp*y[w]+qq*v[w])%yu_;
57                     s=(ss*x[w]+tt*u[w])%yu_;
58                     t=(ss*y[w]+tt*v[w])%yu_;
59                 }
60                 w++;
61                 nn>>=1;
62             }
63             //f(n)/f(n+1)
64             p=(p+q)%yu_;
65             a=1;
66             b=c[i];
67             while (p)
68             {
69                 if ((p & 1)==1)
70                     a=(a*b)%yu;
71                 p>>=1;
72                 b=(b*b)%yu;
73             }
74             result=(result*a)%yu;
75         }
76         printf("%I64d\n",result);
77     }
78     return 0;
79 }

 

posted @ 2017-03-30 19:02  congmingyige  阅读(684)  评论(0编辑  收藏  举报