参考资料
题意简述
给定质数 与整数 ,求最小的非负整数 ,使 ,无解则报告。
解题思路
设 。 为质数, 时 ,可用 BSGS(Baby-Step Giant-Step,大步小步)。
把 写作 (),代入 得:
两侧分别枚举:
- 小步:枚举 从 到 ,将 连同 存入哈希表;
- 大步:枚举 从 到 ,算出 查表,命中即得 。
若有解,最小解必小于 ,故枚举范围足以覆盖。 自小到大、哈希表对相同键保留较大的 ,首个命中即最小的 。(即 )单独特判。
时间复杂度为 。
参考代码
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
ll bsgs(ll b,ll n,ll p)
{
if(n==1)return 0;
unordered_map<ll,ll> mp;
ll m=sqrt(p),k=n;
for(ll j=0;j<m;j++)
{
mp[k]=j;
k=k*b%p;
}
ll t=1;
for(ll i=0;i<m;i++)t=t*b%p;
k=1;
for(ll i=1;i<=m;i++)
{
k=k*t%p;
if(mp.count(k))return i*m-mp[k];
}
return -1;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
ll p,b,n;
cin>>p>>b>>n;
ll res=bsgs(b,n,p);
if(res==-1)cout<<"no solution"<<'\n';
else cout<<res<<'\n';
return 0;
}