离散对数裸题,这道题中p是素数,所以用一般BSGS就好了,这个东西十分巧妙呀。
ax≡b(mod p)
我们可以设
x=Ap√+B
,其中,
0≤A≤p√
,
0≤B<p√
。
那么,我们可以得到
aAp√≡ba−B(mod p)
,我们枚举一下,用map判一判就好了。
还有一点就是,可以不用算逆元,我们可以令
x=Ap√−B
,就得到
aAp√≡baB(mod p)
,A、B的范围改一改就好了。
//BSGS
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll a,b,p,p1,tmp,tmp1,ans;
map <ll,ll> E;
bool flg;
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%lld%lld%lld",&p,&a,&b)!=EOF)
{
if(b==1){
printf("0\n");continue;
}
E.clear();
p1=sqrt(p);
tmp=1;
for(int i=0;i<p1;i++)E[(b*tmp)%p]=i,tmp=(tmp*a)%p;
tmp1=1;flg=false;ans=~0u>>1;
for(int j=1;j<=p1+1;j++)
{
tmp1=(tmp1*tmp)%p;
if(E.count(tmp1)){
ans=min(ans,j*p1-E[tmp1]);
flg=true;
break;
}
}
if(flg)printf("%d\n",ans);
else printf("no solution\n");
}
return 0;
}