拓展BSGS算法及其应用

当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\n");
75         else printf("%d\n",ans);
76     }
77     return 0;
78 }

给哈希好评,哪天好好整理一下

猜你喜欢

转载自www.cnblogs.com/aininot260/p/9491650.html