扩展版 AC 代码。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<cmath>
using namespace std;
typedef long long ll;
map <ll,int> H;
ll GCD(ll a,ll b)
{
if (a<b) return GCD(b,a);
if (!b) return a;
return GCD(b,a%b);
}
ll ExGCD(ll a,ll b,ll &x,ll &y){
ll d;
if(b==0) x=1,y=0,d=a;
else
{
d=ExGCD(b,a%b,y,x),y-=a/b*x;
}
return d;
}
ll mydcwfypow(ll x,int y,ll p)
{
ll ans=1;
while (y)
{
if (y&1) ans=ans*x,ans%=p;
x*=x;y>>=1;x%=p;
}
return ans;
}
int ExBSGS(ll a,ll b,ll p)
{
H.clear();
ll d=1,g=0,gcd;b%=p;
if (b==1||p==1) return 0;
while ((gcd=GCD(a,p))^1)
{
if (b%gcd) return -1;
b/=gcd;p/=gcd;d*=(a/gcd);d%=p;g++;
if (d==b) return g;
}
int t=ceil(sqrt(p*1.0));
ll now=1,x,y;
ExGCD(d,p,x,y);
x=(x%p+p)%p;
b*=x;b%=p;now=b;
for (int i=0;i<t;++i,now*=a,now%=p) H[now]=i;
ll powt=mydcwfypow(a,t,p);now=powt;
for (int i=t;i<=t*t;i+=t,now*=powt,now%=p)
{
if (H.find(now)!=H.end()) return i-H[now]+g;
}
return -1;
}
int main()
{
ll a,p,b;
scanf("%lld%lld%lld",&p,&a,&b);
int ans=ExBSGS(a,b,p);
if (ans!=-1) printf("%d\n",ans);
else puts("no solution");
return 0;
}
前面的 ExBSGS 在 扩展版 BSGS 过了,却在这里全输出 "no solution"。
???