题意:
,解最小X满足同余式
分析:
扩展BSGS算法:
这时a,p不一定互质,先祭上初等数论的模公式:
于是我们可以一直提出gcd(a,p),直到二者互质,假设经过t次后二者互质:
如果n 除不尽 v ,则无解,否则换元,x = x - t,n = n/v,p = p/c,a^t/v 放两边都行,带入BSGS求最小解为:i * m - j + t,
但是最小解也有可能在[1,t]中,所以在提公因子时必须特判 a^t/v == n/v (mod p)?
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a,n,p;
ll qpow(ll a,ll x)
{
ll res = 1;
while(x){
if(x&1) res = res * a % p;
a = a * a % p;
x >>= 1;
}
return res % p;
}
int exbsgs()
{
ll g = __gcd(a,p);
ll step = 0,b = 1;
while(g != 1){
if(n%g) return -1;
n /= g; p /= g; step++;
b = b*(a/g) % p;
g = __gcd(a,p);
if(n == b) return step;
}
map<ll,int> mp;
int k = ceil(sqrt(p*1.0));
ll v = n;
for(int j = 1; j <= k ;++j){
v = v * a % p;
mp[v] = j;
}
v = qpow(a,k);
ll vv = b;
for(int i = 1; i <= k+1; ++i){
vv = vv * v % p;
if(mp[vv]) return i * k - mp[vv] + step;
}
return -1;
}
int main()
{
while(cin>>a>>p>>n){
if(n>=p) {cout<<"Orz,I can’t find D!"<<endl;continue;}
int ans = exbsgs();
if(ans == -1) cout<<"Orz,I can’t find D!"<<endl;
else cout<<ans<<endl;
}
return 0;
}