扩展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。
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 }