本文介绍了一种解决离散对数问题的有效算法——Baby-Step Giant-Step (BSGS)。通过详细的代码实现展示了如何求解形如a^x ≡ b (mod p)的问题,并使用了高效的指数和模运算技巧。
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<map>#define ll long longusingnamespacestd;
inlineint read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int a,b,p;
map<int,int>mp;
int power(int x,int y,int p)
{
int ans=1;
while (y)
{
if (y&1) ans=(ll)ans*x%p;
y>>=1;x=(ll)x*x%p;
}
return ans;
}
int gcd(int a,int b)
{
return (b)?gcd(b,a%b):a;
}
inlinevoid EX_BSGS(int a,int b,int p)
{
if (p==1){puts("0");return;}
a%=p;b%=p;if (!a&&!b){puts("1");return;}
if (b==1){puts("0");return;}
if (!a){puts("No Solution");return;}
int d,step=0,k=1;
while ((d=gcd(a,p))!=1)
{
if (b%d){puts("No Solution");return;}
step++;p/=d;b/=d;k=(ll)k*a/d%p;
if (b==k){printf("%d\n",step);return;}
}
int m=ceil(sqrt(p)),t=b;mp.clear();
for (int i=0;i<=m;i++){mp[t]=i;t=(ll)t*a%p;}
int A=power(a,m,p);
t=(ll)k*A%p;
for (int i=1;i<=m;i++)
{
int ans=t;t=(ll)t*A%p;
if (mp.find(ans)!=mp.end())
{
ans=i*m-mp[ans]+step;
printf("%d\n",ans);
return;
}
}
puts("No Solution");
}
int main()
{
a=read();p=read();b=read();
for (;a+b+p;a=read(),p=read(),b=read())EX_BSGS(a,b,p);
return0;
}