Poj Solution 2447

http://poj.org/problem?id=2447

#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef unsigned __int64 u64;
#define MAX 30
#define MAXN 5
u64 len, dig, limit;
u64 factor[MAXN];
u64 mod(u64 a, u64 b, u64 n){
        if(!a)return 0;
        else return ( ((a&dig)*b)%n + (mod(a>>len,b,n)<<len)%n )%n;
}
u64 by(u64 a, u64 b, u64 n){
            u64 p;
            p = 8, len = 61;
        while(p<n){
                    p<<=4;
                    len -=4;
        }
            dig = ((limit/p)<<1) - 1; 
        return mod(a,b,n);
}
u64 random(){//产生随机数 
            u64 a;
            a = rand();
            a *= rand();
            a *= rand();
            a *= rand();
        return a;
}
u64 square_multiply(u64 x, u64 c, u64 n){//(x^c)%n快速算法 
            u64 z=1;
        while(c){
                if(c%2==1)z = by(z,x,n);
                    x = by(x,x,n);
                    c=(c>>1);
        }
        return z;
}
bool Miller_Rabin(u64 n){//Miller_Rabin素数测试 
    if(n<2)return false;
        if(n==2)return true;
        if(!(n&1))return false;
            u64 k = 0, i, j, m, a;
            m = n - 1;
        while(m%2==0)m=(m>>1),k++;
        for(i=0;i<MAX;i++){
                    a = square_multiply(random()%(n-1)+1, m, n);//平方乘
                if(a==1)continue;
                for(j=0;j<k;j++){
                        if(a==n-1)break;
                            a = by(a,a,n);
                }
                if(j<k)continue;
                return false ;
        }
        return true;
}
u64 gcd(u64 a,u64 b){
        if(a==0) return b;
        else return gcd(b%a,a);
}
u64 f(u64 x, u64 n ){
        return (by(x,x,n)+1)%n;
}
u64 Pollard(u64 n){
                if(n<=2)return 0;
                if(!(n&1))return 2; 
            u64 i, p, x,xx;
        for(i=0;i<MAX;i++){                                 
                    x = random()%n; //或者直接用 x = i
                    xx = f(x,n);
                    p = gcd((xx+n-x)%n , n);
                while(p==1){
                            x = f(x,n);
                            xx = f(f(xx,n),n);
                            p = gcd((xx+n-x)%n,n)%n;
                }
                if(p)return p;
        }
        return 0;
}
u64 prime(u64 a){
        if(Miller_Rabin(a))return a;
            u64 t = Pollard(a);
        if(t!=0)
        {return prime(t);}
           
}
u64 Euclid(u64 a,u64 b,__int64 &x,__int64 &y)
{
 if(b==0)
 { 
     x=1,y=0;
  return a;
 } 
 u64 t,d;
 if(b!=0)
 d=Euclid(b,a%b,x,y);
 t=x;
 x=y;
 if(b!=0)
 y=t-a/b*y;
 return d;
}
int main(){
            u64 c,e,n,i,j,m,t,n0,T,ans,l;
        __int64 T0,x,y,d;
            limit = 1;
            limit = limit<<63; 
        while(scanf("%I64u%I64u%I64u",&c,&e,&n)!=EOF){
              m=0;n0=n;
               while(n%2==0){n/=2;factor[m++]=2;}
               while(n>1){
                        if(Miller_Rabin(n))break;
                            t = prime(n);
                            factor[m++] = t;
                        if(t!=0)
                            n/=t;
                }
               if(n>1)factor[m++]=n;
               //for(l=0;l<m;l++)printf("%I64un",factor[l]);
                   T0=(__int64)(factor[0]-1)*(factor[1]-1);
          T=(u64)T0;
               Euclid(e,T,x,y);
                   d=x;
      //printf("%I64dn",d);
      //while(d<0)d+=T0;
                   d=(d%T0+T0)%T0;
               //d=(__int64)d;
     // printf("%I64d %I64dn",d,T0);
                   ans=square_multiply(c,(u64)d,n0);
               printf("%I64un",ans);
                   
}
}
											
This entry was posted in poj. Bookmark the permalink.