当C不是素数的时候,之前介绍的BSGS就行不通了,需要用到拓展BSGS算法
方法转自https://blog.csdn.net/zzkksunboy/article/details/73162229
典型例题是POJ3243
1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 using namespace std; 5 struct Hashmap 6 { 7 static const int Ha=999917,maxe=46340; 8 int E,lnk[Ha],son[maxe+5],nxt[maxe+5],w[maxe+5]; 9 int top,stk[maxe+5]; 10 void clear() {E=0;while (top) lnk[stk[top--]]=0;} 11 void Add(int x,int y) {son[++E]=y;nxt[E]=lnk[x];w[E]=0X7fffffff;lnk[x]=E;} 12 bool count(int y) 13 { 14 int x=y%Ha; 15 for (int j=lnk[x];j;j=nxt[j]) 16 if (y==son[j]) return true; 17 return false; 18 } 19 int& operator [] (int y) 20 { 21 int x=y%Ha; 22 for (int j=lnk[x];j;j=nxt[j]) 23 if (y==son[j]) return w[j]; 24 Add(x,y);stk[++top]=x;return w[E]; 25 } 26 }f; 27 int gcd(int a,int b) 28 { 29 return b==0?a:gcd(b,a%b); 30 } 31 int exgcd(int a,int b,int &x,int &y) 32 { 33 if(b==0) {x=1;y=0;return a;} 34 int r=exgcd(b,a%b,x,y); 35 int t=x;x=y;y=t-a/b*y; 36 return r; 37 } 38 int exBSGS(int A,int B,int C) 39 { 40 if(C==1) if(B==0) return A!=1; else return -1; 41 if(B==1) if(A!=0) return 0; else return -1; 42 if(A%C==0) if(B==0) return 1; else return -1; 43 int r,D=1,num=0; 44 while((r=gcd(A,C))>1) 45 { 46 if(B%r) return -1; 47 num++; 48 B/=r;C/=r;D=((long long)D*A/r)%C; 49 } 50 for(int i=0,tmp=1;i<num;i++,tmp=((long long)tmp*A)%C) 51 if(tmp==B) return i; 52 int m=ceil(sqrt(C)),Base=1;f.clear(); 53 for(int i=0;i<=m-1;i++) 54 { 55 f[Base]=min(f[Base],i); 56 Base=((long long)Base*A)%C; 57 } 58 for(int i=0;i<=m-1;i++) 59 { 60 int x,y,r=exgcd(D,C,x,y); 61 x=((long long)x*B%C+C)%C; 62 if(f.count(x)) return i*m+f[x]+num; 63 D=((long long)D*Base)%C; 64 } 65 return -1; 66 } 67 int main() 68 { 69 int A,B,C; 70 while(scanf("%d%d%d",&A,&C,&B)==3) 71 { 72 if(!A&&!B&&!C) break; 73 int ans=exBSGS(A,B,C); 74 if(ans==-1) printf("No Solution "); 75 else printf("%d ",ans); 76 } 77 return 0; 78 }
给哈希好评,哪天好好整理一下