题目大意:求使得
ax≡b(modp)
成立的最小自然数b
思路:任意一个
ax=ab∗p√+c
然后算出后面的值,枚举并在hash表中查询,如果p不是质数 p/=g;b/=g;t=t*(a/g)%p;
x=x`+1
Code:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
ll a,b,p;
ll gcd(int a,int b) {return b==0?a:gcd(b,a%b);}
ll qpow(ll a,ll b,ll mod)
{
ll ret=1;
for(ll i=b;i;i>>=1,a=(a*a)%mod) {
if(i&1) ret*=a,ret%=mod;
}
return ret;
}
ll BSGS()
{
a%=p;b%=p;
if(b==1) return 0;
ll cnt=0,t=1;
for(ll g=gcd(a,p);g!=1;g=gcd(a,p)) {
if(b%g) return -1;
p/=g;b/=g;t=t*(a/g)%p; cnt++;
if(t==b) return cnt;
}
map<int,int>hash;
ll m=ll(sqrt(1.0*p)+1),
base=qpow(a,m,p),now=t,tmp=b;
for(int i=0;i<m;i++,tmp=(tmp*a)%p) {
hash[tmp]=i;
}
for(int i=1;i<=m+1;i++) {
now=now*base%p;
if(hash.count(now)) {
return i*m-hash[now]+cnt;
}
}
return -1;
}
int main()
{
while(scanf("%lld%lld%lld",&a,&p,&b)) {
if(a==b&&b==p&&a==0) break;
ll ans=BSGS();
ans==-1?puts("No Solution"):printf("%lld\n",ans);
}
return 0;
}