题目链接: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 }

 

posted on 2012-05-11 09:22  奋斗青春  阅读(1075)  评论(2编辑  收藏  举报