poj3070_斐波那契数列(Fibonacci)

用矩阵求斐波那契数列,快速幂log(n),只用求最后4位(加和乘的运算中前面的位数无用)

 

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 int main()
 5 {
 6     /*
 7     (x y)(x y)=  (x*x+y*s x*y+y*t) =(x*x+y*s  y*(x+t))
 8     (s t)(s t)   (s*x+t*s s*y+t*t)  (s*(x+t)  t*t+y*s)
 9     (x y)(a b)= (x*a+y*c x*b+y*d)
10     (s t)(c d)  (s*a+t*c s*b+t*d)
11     (a b)(f1=1)=(a+b)
12     (c d)(f2=1) (c+d)
13     */
14     //(a,b)(c,d)一开始为E2
15     long n,x,y,s,t,xx,yy,ss,tt,a,b,c,d,aa,bb,cc,dd;
16     while (scanf("%ld",&n))
17     {
18         if (n==0)
19         {
20             printf("0\n");
21             continue;
22         }
23         else if (n==-1)
24             break;
25         n-=2;
26         x=0;
27         y=1;
28         s=1;
29         t=1;
30         a=1;
31         b=0;
32         c=0;
33         d=1;
34         while (n)
35         {
36             if (n%2==1)
37             {
38                 aa=a;
39                 bb=b;
40                 cc=c;
41                 dd=d;
42                 a=(x*aa+y*cc)%10000;
43                 b=(x*bb+y*dd)%10000;
44                 c=(s*aa+t*cc)%10000;
45                 d=(s*bb+t*dd)%10000;
46             }
47             xx=x;
48             yy=y;
49             ss=s;
50             tt=t;
51             x=(xx*xx+yy*ss)%10000;
52             y=(yy*(xx+tt))%10000;
53             s=(ss*(xx+tt))%10000;
54             t=(tt*tt+yy*ss)%10000;
55             n=n/2;
56         }
57         printf("%ld\n",(c+d)%10000);
58     }
59 
60     return 0;
61 }
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 int main()
 5 {
 6     /*
 7     (x y)(x y)=  (x*x+y*s x*y+y*t) =(x*x+y*s  y*(x+t))
 8     (s t)(s t)   (s*x+t*s s*y+t*t)  (s*(x+t)  t*t+y*s)
 9     (x y)(a b)= (x*a+y*c x*b+y*d)
10     (s t)(c d)  (s*a+t*c s*b+t*d)
11     (a b)(f1=1)=(a+b)
12     (c d)(f2=1) (c+d)
13     */
14     //(a,b)(c,d)一开始为E2
15     long n,x[32],y[32],s[32],t[32],a[32],b[32],c[32],d[32],w,r,i;
16     x[0]=0;
17     y[0]=1;
18     s[0]=1;
19     t[0]=1;
20     a[0]=1;
21     b[0]=0;
22     c[0]=0;
23     d[0]=1;
24     for (i=1;i<32;i++)
25     {
26         x[i]=(x[i-1]*x[i-1]+y[i-1]*s[i-1])%10000;
27         y[i]=(y[i-1]*(x[i-1]+t[i-1]))%10000;
28         s[i]=(s[i-1]*(x[i-1]+t[i-1]))%10000;
29         t[i]=(t[i-1]*t[i-1]+y[i-1]*s[i-1])%10000;
30     }
31     while (scanf("%ld",&n))
32     {
33         if (n==0)
34         {
35             printf("0\n");
36             continue;
37         }
38         else if (n==-1)
39             break;
40         n-=2;
41         w=0;
42         r=0;
43         while (n)
44         {
45             if (n%2==1)
46             {
47                 a[r+1]=(x[w]*a[r]+y[w]*c[r])%10000;
48                 b[r+1]=(x[w]*b[r]+y[w]*d[r])%10000;
49                 c[r+1]=(s[w]*a[r]+t[w]*c[r])%10000;
50                 d[r+1]=(s[w]*b[r]+t[w]*d[r])%10000;
51                 r++;
52             }
53             w++;
54             n=n/2;
55         }
56         printf("%ld\n",(c[r]+d[r])%10000);
57     }
58     return 0;
59 }

 

posted @ 2017-03-26 17:02  congmingyige  阅读(259)  评论(0编辑  收藏  举报