参考资料
(OI-WIKI)[https://oi-wiki.org/math/bsgs/]
(Miskcoo)[http://blog.miskcoo.com/2015/05/discrete-logarithm-problem]
BSGS算法流程
给定a,b,p, 求解
复杂度O(√p)
具体看Miskcoo的教程
代码
#include<bits/stdc++.h> typedef long long ll; const int MOD=76543; int flag; ll hs[MOD],head[MOD],next[MOD],id[MOD],top; ll inv(ll x,ll p,ll mod){ ll v=1; while(p){ if(p&1)v=x*v%mod; x=x*x%mod; p>>=1; } return v; } void insert(ll x,int y){ ll k=x%MOD; hs[++top]=x,id[top]=y,next[top]=head[k],head[k]=top; } ll find(int x){ ll k=x%MOD; for(int i=head[k];i!=0;i=next[i]) if(hs[i]==x)return id[i]; return -1; } ll bsgs(ll a,ll p,ll b) { memset(head,0,sizeof(head)),top=0; a%=p,b%=p; if(b==1)return 0; ll cnt=0; ll t=1; for(ll g=std::__gcd(a,p);g!=1;g=std::__gcd(a,p)){ if(b%g)return -1; p=p/g; b=b/g; t=t*a/g%p; if(b==t)return 0; cnt++; } ll m=ceil(sqrt(p*1.0)); ll x=t,a_B=1; for(ll i=0;i<m;i++,a_B=a_B*a%p)insert(b*a_B%p,i); a_B=inv(a,m,p); for(ll A=m;;A+=m){ x=x*a_B%p; int j=find(x); if(j!=-1)return A-j+cnt; if(A>p)break; } return -1; } int main() { ll a,p,b; while(scanf("%lld%lld%lld",&a,&p,&b)!=EOF&&(a|b|p)) { if(p==1) {puts("0");continue;} flag=0; ll x=bsgs(a,p,b); if(x==-1)puts("No Solution"); else printf("%lld\n",x); } }