給定,求一個使其滿足
可以解決爲質數的情況
令
令
有
兩邊同乘 得
我們先將右邊的 全部求出來存到一個表裏,這樣預處理時間複雜度爲
之後再枚舉 到 ,看錶裏有沒有 ,有的話就有一組解
再反向求出即可
當不是質數時
令
有
把那個除掉
然後重複這個過程直到互質
除掉後可能仍與有公約數,與互質
顯然,在這個過程中如果不能被整除就無解
到最後會得到這樣的方程
是由的冪除以若干個因子得到的 肯定互質
兩邊乘以(逆元)
用對求解即可
最後記得加上
ksm(a,b);//return a^b
gcd(a,b);//return gcd(a,b)
//{{{bsgs
int bsgs (int a,int b,int p)//return a^x ≡ b mod p 's x
{
a%=p;
if (!a&&!b) return 1;
if (!a) return -1;
int m=sqrt(p);
map <int,int> mp;//這裏用的map 也可以自己打個哈希
int t=b%p;
mp[t]=0;
for (int i=1;i<=m;++i) mp[t=1ll*t*a%p]=i;
t=1;
int mi=ksm(a,m);
for (int i=1;1ll*i*i<=p+1;++i){
t=1ll*t*mi%p;
if (mp.count(t)) return ((1ll*i*m%p-mp[t])%p+p)%p;
}
return -1;
}
//}}}
//{{{exbsgs
int exbsgs (int a,int b,int p)//a^x ≡ b mod p 's x
{
if (b==1) return 0;
int cnt=0,t=1;
for (int g=gcd(a,p);g!=1;g=gcd(a,p)){
if (b%g) return -1;
++cnt,b/=g,p/=g;
t=1ll*t*a/g%p;
if (b==t) return cnt;
}
int x=bsgs(a,1ll*ksm(t,p-2)*b%p,p);
if (x!=-1) x+=cnt;
return x;
}
//}}}
如有哪裏講得不是很明白或是有錯誤,歡迎指正
如您喜歡的話不妨點個贊收藏一下吧