poj 3243 Clever Y 高次方程
1 Accepted 8508K 579MS C++ 2237B/** 2 hash的强大,,还是高次方程,不过要求n不一定是素数 3 **/ 4 #include <iostream> 5 #include <cstdio> 6 #include <cmath> 7 #include <cstring> 8 #include <algorithm> 9 using namespace std; 10 long long a,b,n; 11 const int maxn = 499991; 12 bool Hash[maxn]; 13 long long val[maxn]; 14 long long idx[maxn]; 15 16 long long gcd(long long a,long long b){ 17 if(b==0) 18 return a; 19 return gcd(b,a%b); 20 } 21 22 void ex_gcd(long long a,long long b,long long &x,long long &y){ 23 if(b==0){ 24 x=1; 25 y=0; 26 return ; 27 } 28 ex_gcd(b,a%b,x,y); 29 long long tmp= x-(a/b)*y; 30 x = y; 31 y = tmp; 32 return ; 33 } 34 35 void Insert(long long id,long long num){ 36 long long k = num%maxn; 37 while(Hash[k]&&val[k]!=num){ 38 k++; 39 if(k==maxn) k = k-maxn; 40 } 41 if(!Hash[k]){ 42 Hash[k] = true; 43 val[k] = num; 44 idx[k] = id; 45 } 46 return; 47 } 48 49 long long found(long long num){ 50 long long k = num%maxn; 51 while(Hash[k]&&val[k]!=num){ 52 k++; 53 if(k==maxn) k-=maxn; 54 } 55 if(Hash[k]){ 56 return idx[k]; 57 } 58 return -1; 59 } 60 61 long long baby_step(long long a,long long b,long long n){ 62 long long temp =1; 63 long long i; 64 for(i=0;i<=100;i++){ 65 if(temp==b%n) return i; 66 temp = temp*a%n; 67 } 68 long long tmp,d =1,cnt=0; 69 memset(Hash,false,sizeof(Hash)); 70 memset(val,-1,sizeof(val)); 71 memset(idx,-1,sizeof(idx)); 72 73 while((tmp=gcd(a,n))!=1){ 74 if(b%tmp) 75 return -1; 76 cnt++; 77 n = n/tmp; 78 b = b/tmp; 79 d =d*a/tmp%n; 80 } 81 long long cur =1; 82 long long m = ceil(sqrt(n+0.5)); 83 for(i=0;i<m;i++){ 84 Insert(i,cur); 85 cur = cur*a%n; 86 } 87 long long x,y; 88 for(i=0;i<m;i++){ 89 ex_gcd(d,n,x,y); 90 x = x*b%n; 91 x = (x%n+n)%n; 92 long long k = found(x); 93 if(k!=-1) 94 return i*m+k+cnt; 95 d = d*cur%n; 96 } 97 return -1; 98 } 99 100 int main() 101 { 102 while(scanf("%I64d%I64d%I64d",&a,&n,&b)==3){ 103 if(a==0&&b==0&&n==0) 104 break; 105 long long res = baby_step(a,b,n); 106 if(res==-1){ 107 printf("No Solution\n"); 108 }else{ 109 printf("%I64d\n",res); 110 } 111 } 112 return 0; 113 }