BSGS及扩展BSGS模板
BSGS
#include <iostream>//poj2417 #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> #define ll long long using namespace std; const int maxint=((1<<30)-1)*2+1; int A,B,C; struct Hashmap{ static const int Ha=999917,maxe=46340; int E,lnk[Ha],son[maxe+5],nxt[maxe+5],w[maxe+5]; int top,stk[maxe+5]; void clear() {E=0;while(top) lnk[stk[top--]]=0;} void Add(int x,int y){son[++E]=y;nxt[E]=lnk[x];w[E]=maxint;lnk[x]=E;} bool count(int y) { int x=y%Ha; for(int j=lnk[x];j;j=nxt[j]) if(y==son[j]) return true; return false; } int& operator [] (int y) { int x=y%Ha; for(int j=lnk[x];j;j=nxt[j]) if(y==son[j]) return w[j]; Add(x,y);stk[++top]=x;return w[E]; } }; Hashmap f; int exgcd(int a,int b,int &x,int &y) { if(!b) {x=1;y=0;return a;} int r=exgcd(b,a%b,x,y),t=x;x=y;y=t-(a/b)*y; return r; } int BSGS(int A,int B,int C) { if(C==1) if(!B) return A!=1; else return -1; if(B==1) if(A) return 0; else return -1; if(A%C==0) if(!B) return 1;else return -1; int m=ceil(sqrt(C)),D=1,Base=1;f.clear(); for(int i=0;i<=m-1;i++)//先把A^j存进哈希表 { f[Base]=min(f[Base],i); Base=((ll)Base*A)%C; } for(int i=0;i<=m-1;i++) { int x,y,r=exgcd(D,C,x,y); x=((ll)x*B%C+C)%C;//扩欧求A^j if(f.count(x)) return i*m+f[x];//找到解 D=((ll)D*Base)%C; } return -1; } int main() { while(~scanf("%d%d%d",&C,&A,&B)) { int ans=BSGS(A,B,C); if(ans==-1) printf("no solution\n"); else printf("%d\n",ans); } return 0; }
扩展BSGS
#include <iostream>//poj3243 #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> #define ll long long using namespace std; const int maxint=((1<<30)-1)*2+1; int A,B,C; struct Hashmap{ static const int Ha=999917,maxe=46340; int E,lnk[Ha],son[maxe+5],nxt[maxe+5],w[maxe+5]; int top,stk[maxe+5]; void clear() {E=0;while(top) lnk[stk[top--]]=0;} void Add(int x,int y){son[++E]=y;nxt[E]=lnk[x];w[E]=maxint;lnk[x]=E;} bool count(int y) { int x=y%Ha; for(int j=lnk[x];j;j=nxt[j]) if(y==son[j]) return true; return false; } int& operator [] (int y) { int x=y%Ha; for(int j=lnk[x];j;j=nxt[j]) if(y==son[j]) return w[j]; Add(x,y);stk[++top]=x;return w[E]; } }; Hashmap f; int gcd(int a,int b){ if(!b) return a; else return gcd(b,a%b); } int exgcd(int a,int b,int &x,int &y) { if(!b) {x=1;y=0;return a;} int r=exgcd(b,a%b,x,y),t=x; x=y;y=t-(a/b)*y; return r; } int exBSGS(int A,int B,int C) { if(C==1) if(!B) return A!=1;else return -1; if(B==1) if(A) return 0;else return -1; if(A%C==0) if(!B) return 1;else return -1; int r,D=1,num=0; while((r=gcd(A,C))>1) { if(B%r) return -1;num++; B/=r;C/=r;D=((ll)D*A/r)%C; } for(int i=0,now=1;i<num;i++,now=((ll)now*A)%C) { if(now==B) return i; } int m=ceil(sqrt(C)),Base=1;f.clear(); for(int i=0;i<=m-1;i++) { f[Base]=min(f[Base],i); Base=((ll)Base*A)%C; } for(int i=0;i<=m-1;i++) { int x,y,r=exgcd(D,C,x,y); x=((ll)x*B%C+C)%C; if(f.count(x)) return i*m+f[x]+num; D=((ll)D*Base)%C; } return -1; } int main() { while(~scanf("%d%d%d",&A,&C,&B))//A^y mod C=B { if(!A&&!B&&!C) break; int ans=exBSGS(A,B,C); if(ans==-1) printf("No Solution\n"); else printf("%d\n",ans); } return 0; }