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 }