题目描述
题解
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
using namespace std;
#define LL long long
LL a,b,P;
map <LL,LL> hash;
LL gcd(LL a,LL b)
{
if (!b) return a;
else return gcd(b,a%b);
}
LL fast_pow(LL a,LL p)
{
LL ans=1LL;
for (;p;p>>=1LL,a=a*a%P)
if (p&1LL)
ans=ans*a%P;
return ans;
}
LL exbsgs(LL a,LL b,LL p)
{
if (b==1LL) return 0;
LL t,d=1,k=0;
while ((t=gcd(a,p))!=1)
{
if (b%t) return -1;
++k,b/=t,p/=t,d=d*(a/t)%p;
if (b==d) return k;
}
hash.clear();
LL m=ceil(sqrt(p));LL a_m=fast_pow(a,m);
LL mul=b;
for (LL j=1;j<=m;++j)
{
mul=mul*a%p;
hash[mul]=j;
}
for (LL i=1;i<=m;++i)
{
d=d*a_m%p;
if (hash[d]) return i*m-hash[d]+k;
}
return -1;
}
int main()
{
while (~scanf("%lld%lld%lld",&a,&P,&b))
{
if (!a&&!P&&!b) break;
LL ans=exbsgs(a%P,b%P,P);
if (ans!=-1LL) printf("%lld\n",ans);
else puts("No Solution");
}
}
总结
抽空学一下手写hash