Solution
$$a^{x} \equiv b\pmod{p}$$
$$a^{x}+k \ast p =b$$
设d为gcd(a,p)
$$\frac{a^x}{d}+\frac{k \ast p}{d}=\frac{b}{d}$$
可以看出若b不能被d整除则无解
$$\frac{a^k}{d} \ast a^{x-k} \equiv \frac{b}{d}\pmod{\frac{p}{d}}$$
这样直到p/d为质数即可用普通BSGS算法求解
Code
#include <cstdio> #include <cstdlib> #include <map> #include <cmath> #define ll long long using namespace std; map <ll,int> ha; ll a,b,p,x; int k; ll gcd(ll a,ll b) { if(!b) return a; return gcd(b,a%b); } ll qpow(ll x,ll y,ll p) { ll an=1; while(y) { if(y&1) an=an*x%p; x=x*x%p,y>>=1; } return an%p; } void solve(ll a,ll b,ll p) { a%=p,b%=p; x=1,k=0; while(1) { ll d=gcd(a,p); if(d==1) break; if(b%d){puts("No Solution");return ;} b/=d,p/=d,k++,x=(x*a/d)%p; if(b==x){printf("%d\n",k);return ;} } ll y=sqrt(p); ha.clear(); for(ll i=0,t=b;i<y;i++,t=t*a%p) ha[t]=i+1; ll t=qpow(a,y,p),now=x*t%p; for(ll i=1;i<=y;i++,now=now*t%p) if(ha.count(now)){printf("%lld\n",i*y-ha[now]+1+k);return;} puts("No Solution"); } int main() { while(scanf("%lld%lld%lld",&a,&p,&b) && a+b+p>0) solve(a,b,p); return 0; }