题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3221
矩阵乘法和数学的结合。
由题目意思可知:f[n]=f[n-1]*f[n-2];
f的前面几项可以罗列出来:
a^1*b^0,a^0*b^1,a^1*b^1,a^1*b^2,a^2*b^3....
可以发现a的指数和b的指数均类似于斐波那契数列。
用矩阵的快速幂可以很快的求出第n项a和b的指数分别是多少。
但是这个指数会非常大,存不下来,需要对一个数去模。
这里需要用到一个公式:
A^B%C=A^( B%Phi[C] + Phi[C] )%C (B>=Phi[C])
Phi[C]表示不大于C的数中与C互质的数的个数,可以用欧拉函数来求:
找到C的所有素因子。
Phi[C]=C*(1-1/q1)*(1-1/q2)*(1-1/q3)*....*(1-1-qk);
q1,q2,q3...qk表示C的素因子。
到这里基本上就能解决了。
code:
View Code
1 # include<stdio.h> 2 # include<string.h> 3 # include<stdlib.h> 4 # define N 1000005 5 int visit[N],prime[N],K; 6 __int64 P,Phi; 7 struct matrix{ 8 __int64 A[2][2]; 9 }; 10 void intt() 11 { 12 int i,j; 13 memset(visit,0,sizeof(visit)); 14 for(i=2;i<=1000;i++) 15 { 16 if(visit[i]==0) 17 { 18 for(j=i+i;j<=1000000;j+=i) 19 { 20 visit[j]=1; 21 } 22 } 23 } 24 K=0; 25 for(j=2;j<=1000000;j++) 26 if(visit[j]==0) prime[++K]=j; 27 } 28 matrix power(matrix ans1,matrix ans2) 29 { 30 int i,j,k; 31 matrix ans; 32 for(i=0;i<=1;i++) 33 { 34 for(j=0;j<=1;j++) 35 { 36 ans.A[i][j]=0; 37 for(k=0;k<=1;k++) 38 { 39 ans.A[i][j]+=ans1.A[i][k]*ans2.A[k][j]; 40 if(ans.A[i][j]>Phi) 41 { 42 ans.A[i][j]=ans.A[i][j]%Phi+Phi; 43 } 44 } 45 } 46 } 47 return ans; 48 } 49 matrix mod(matrix un,__int64 k) 50 { 51 matrix ans; 52 ans.A[0][0]=1; 53 ans.A[0][1]=0; 54 ans.A[1][0]=0; 55 ans.A[1][1]=1; 56 while(k) 57 { 58 if(k%2) ans=power(ans,un); 59 un=power(un,un); 60 k/=2; 61 } 62 return ans; 63 } 64 __int64 mod1(__int64 a,__int64 k) 65 { 66 __int64 ans; 67 ans=1; 68 while(k) 69 { 70 if(k%2) 71 { 72 ans=ans*a; 73 ans%=P; 74 } 75 a=a*a; 76 a%=P; 77 k/=2; 78 } 79 return ans%P; 80 } 81 int main() 82 { 83 int i,ncase,t; 84 __int64 a,b,aa,bb,n,num,num1,num2; 85 //freopen("3221.in","r",stdin); 86 //freopen("32211.out","w",stdout); 87 matrix init,ans; 88 intt(); 89 scanf("%d",&ncase); 90 for(t=1;t<=ncase;t++) 91 { 92 scanf("%I64d%I64d%I64d%I64d",&a,&b,&P,&n); 93 printf("Case #%d: ",t); 94 if(n==1) {printf("%I64d\n",a%P);continue;} 95 else if(n==2) {printf("%I64d\n",b%P); continue;} 96 else if(n==3) {printf("%I64d\n",a*b%P);continue;} 97 if(P==1) {printf("0\n");continue;} 98 init.A[0][0]=0; 99 init.A[0][1]=1; 100 init.A[1][0]=1; 101 init.A[1][1]=1; 102 // A^B % C = A ^ ( B % phi[C] + phi[C] ) %C ( B >= phi[C] ) ,phi[C]表示与C互质的数的个数 103 Phi=1; 104 num=P; 105 for(i=1;i<=K;i++) 106 { 107 if(prime[i]>P) break; 108 if(P%prime[i]==0) {Phi*=(prime[i]-1);num/=prime[i];} 109 } 110 ///phi[C]=C*(1-1/p1)*(1-1/p2)*...*(1-1/pt);p1,p2,...pt表示C的素因子 111 Phi*=num;//Phi表示phi[C] 112 113 114 ans=mod(init,n-3);///求指数 115 116 117 num1=ans.A[1][1];///a的指数 118 num2=ans.A[0][1]+ans.A[1][1];///b的指数 119 if(num2>Phi) num2=num2%Phi+Phi; 120 121 aa=mod1(a,num1);///a^num1%p; 122 bb=mod1(b,num2);//b^num2%p; 123 124 printf("%I64d\n",aa*bb%P); 125 } 126 return 0; 127 }