P3846 [TJOI2007] 可愛的質數/【模板】BSGS
阿新 • • 發佈:2020-08-13
稍後更新
題面
題意:
給定\(p,b,n\),求滿足\(b^{x}\equiv n\ (mod\ p)\)的最小的\(x\)的值
演算法分析:
根據題意我們很容易想到這個題用\(BSGS\)(大步小步演算法或北上廣深或拔山蓋世)來做,\(BSGS\)就是用來處理這一類問題的
\(BSGS\)中的\(p\)為質數
實現:
我們考慮柿子\(b^{x}\equiv n\ (mod\ p)\)
根據費馬小定理\(a^{p-1}\equiv 1\ (mod\ p)\)(證明在我的另一篇部落格裡有提到過),且\(a^{0}\equiv 1\ (mod\ p)\)
我們可以發現\(a^{x}\equiv n\ (mod\ p)\)
我們就可以發現\([0, p-2]\)是一個迴圈節,且每個迴圈節都會構成一個\(mod\ p\) 的完全剩餘系
所以我們只需要考慮\(x\in [0,p-2]\)中,\(a^{x}\equiv n\ (mod\ p )\)
然後我們設$m= $
#include<bits/stdc++.h> using namespace std; long long n, b, p, m, ans, now, st; map<long long, int> mp; long long ksm(long long x, long long y){ long long res = 1; while(y){ if(y & 1) res = (res * x) % p; x = (x * x) % p; y >>= 1; } return res % p; } int main(){ mp.clear(); scanf("%d %d %d", &p, &b, &n); if(b % p == 0){ printf("no solution\n"); return 0; } m = ceil(sqrt(p)); now = n % p; mp[now] = 0; for(int i = 1; i <= m; i ++){ now = (now * b) % p; mp[now] = i; } st = ksm(b, m); now = 1; for(int i = 1; i <= m; i ++){ now = (now * st) % p; if(mp[now]){ ans = i * m - mp[now]; printf("%lld\n", ((ans % p) + p) % p); return 0; } } printf("no solution\n"); return 0; }