hdu 3221 Brute-force Algorithm

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

 

你可能感兴趣的:(Algorithm)