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 }

 

posted @ 2014-05-12 21:16  夜晓楼  阅读(152)  评论(0编辑  收藏  举报