扩展Baby Step Giant Step

Baby Step Giant Step: A^X=B(mod C); C为素数。

如果C没有限制就变成扩展Baby Step Giant Step。

参照大牛博客:http://hi.baidu.com/aekdycoin/item/236937318413c680c2cf29d4

实在是太弱了,没用二分,写了一个hash竟然超时,最后还是copy了一个hash。

View Code
  1 # include<stdio.h>
  2 # include<string.h>
  3 # include<stdlib.h>
  4 # include<math.h>
  5 # define INF 65535
  6 int X,Y;
  7 //int Hash[INF],val[INF];
  8 struct hash{
  9     int a,b,next;
 10 }Hash[INF << 1];
 11 int flg[INF + 66];
 12 int top,idx;
 13 void ins(int a,int b){
 14     int k = b & INF;
 15     if(flg[k] != idx){
 16         flg[k] = idx;
 17         Hash[k].next = -1;
 18         Hash[k].a = a;
 19         Hash[k].b = b;
 20         return ;
 21     }
 22     while(Hash[k].next != -1){
 23         if(Hash[k].b == b) return ;
 24         k = Hash[k].next;
 25     }
 26     Hash[k].next = ++ top;
 27     Hash[top].next = -1;
 28     Hash[top].a = a;
 29     Hash[top].b = b;
 30 }
 31 int find(int b){
 32     int k = b & INF;
 33     if(flg[k] != idx) return -1;
 34     while(k != -1){
 35         if(Hash[k].b == b) return Hash[k].a;
 36         k = Hash[k].next;
 37     }
 38     return -1;
 39 }
 40 
 41 int gcd(int a,int b)
 42 {
 43     int tmp;
 44     while(a%b)
 45     {
 46         tmp=a%b;
 47         a=b;
 48         b=tmp;
 49     }
 50     return b;
 51 }
 52 void extend_gcd(int a,int b)
 53 {
 54     int X1,Y1;
 55     if(b==0)
 56     {
 57         X=1;
 58         Y=0;
 59         return;
 60     }
 61     extend_gcd(b,a%b);
 62     X1=Y;
 63     Y1=X-Y*(a/b);
 64     X=X1;
 65     Y=Y1;
 66     
 67 }
 68 int Inval(int a,int b,int n) // 求解方程a*x+b*y=n;
 69 {
 70     int e;
 71     extend_gcd(a,b);
 72     e=(__int64)X*n%b;
 73     return e<0?e+b:e;
 74 }
 75 int pow_mod(int A,int m,int C)
 76 {
 77     int mm,i;
 78     mm=1;
 79     for(i=1;i<=m;i++)
 80         mm=(__int64)mm*A%C;
 81     return mm;
 82 }
 83 /*void insert(int x,int i,int m)
 84 {
 85 int pos;
 86 pos=x%m;
 87 while(Hash[pos]!=-1)
 88 {
 89 pos++;
 90 if(pos==m) pos=0;
 91 }
 92 Hash[pos]=i;
 93 val[pos]=x;
 94 }
 95 int find(int x,int m)
 96 {
 97 int pos,i,pos1;
 98 pos=x%m;
 99 for(i=0;i<m;i++)
100 {
101 pos1=pos+i;
102 if(pos1>=m) pos1-=m;
103 if(Hash[pos1]==-1) break;
104 if(val[pos1]==x) break;
105 }
106 if(i==m) return -1;
107 return Hash[pos1];
108 }*/
109 
110 int babystep(int A,int C,int B)
111 {
112     int i,d,tmp,m,w,mm,ans;
113     __int64 D;
114     top = INF; ++ idx; 
115     d=0;
116     D=1;
117     ans=1;
118     for(i=0;i<=100;i++)
119     {
120         if(ans==B) return i;
121         ans=(__int64)ans*A%C;
122     }
123     tmp=gcd(A,C);
124     while(tmp!=1)
125     {
126         if(B%tmp) return -1;
127         ++d;
128         C/=tmp;
129         B/=tmp;
130         D=D*A/tmp%C;
131         tmp=gcd(A,C);
132     }
133     m=ceil(sqrt((double)C));
134     ans=1;
135     //memset(Hash,-1,sizeof(Hash));
136     for(i=0;i<=m;i++)
137     {
138         //insert(ans,i,m+1);//把A^i%C插入hash表
139         ins(i,ans);
140         ans=(__int64)ans*A%C;
141     }
142     mm=pow_mod(A,m,C); //A^m%C
143     for(i=0;i<=m;i++) // mm^i
144     {
145         tmp=Inval((int)D,C,B);
146         if(tmp>=0 && (w=find(tmp))!=-1) return i*m+w+d;
147         D=D*mm%C;
148     }
149     return -1;
150 }
151 int main()
152 {
153     int K,P,N,ans;
154     while(scanf("%d%d%d",&K,&P,&N)!=EOF)
155     {
156         //if(K==0 && P==0 && N==0) break;
157         if(N>=P) {printf("Orz,I can’t find D!\n");continue;}
158         if(P==1)
159         {
160             if(N==0) printf("0\n");
161             else printf("Orz,I can’t find D!\n");
162             continue;
163         }
164         ans=babystep(K,P,N);
165         if(ans==-1) printf("Orz,I can’t find D!\n");
166         //if(ans==-1) printf("No Solution\n");
167         else printf("%d\n",ans);
168     }
169     return 0;
170 }

 

 

posted on 2012-09-20 16:14  奋斗青春  阅读(471)  评论(0编辑  收藏  举报