题解 P3846 【 [TJOI2007]可爱的质数】
首先,我们回顾一下 Fermat-Oula 定理:
把它乘
通过 Fermat-Oula 定理,我们可以知道
简而言之,
那么,如何构造
第一步(Baby Step):从
第二步(Giant Step):我们通过快速幂可以得到
这样,就可以求得最小解了!
代码:
#include<bits/stdc++.h>
using namespace std;
int ans=2147483647;
map<int,int>mp;
void baby_step(int b,int n,int p)
{
int cs=0,t=sqrt(p-0.5)+1;
while(cs<t)
{
if(!mp[n])mp[n]=cs+1;
n=1ll*n*b%p,cs++;
}
}
int powdv(int b,int t,int p)
{
int ans=1;
while(t)
{
if(t&1)ans=(1ll*ans*b)%p;
t>>=1;
b=(1ll*b*b)%p;
}
return ans;
}
void giant_step(int b,int n,int p)
{
int cs=1,t=sqrt(p-0.5)+1,b2;
b=b2=powdv(b,t,p);
while(cs<=t)
{
if(mp[b])
ans=min(ans,t*cs-mp[b]+1);
b=(1ll*b*b2)%p,cs++;
}
}
int main()
{
int p,b,n;
cin>>p>>b>>n;
baby_step(b,n,p);
giant_step(b,n,p);
if(ans<2147483647)cout<<ans<<endl;
else cout<<"no solution\n";
return 0;
}
最后推荐我的公众号:这里。