贴板子 BZOJ 3239: Discrete Logging//2480: Spoj3105 Mod(两道题输入不同,我这里只贴了3239的代码)
CODE
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int p, a, b;
int gcd(int a, int b) { return b ? gcd(b, a%b) : a; }
inline int qpow(LL a, LL b, LL c) {
LL res = 1;
while(b) {
if(b&1) res = res * a % c;
a = a * a % c; b >>= 1;
}
return res;
}
map<int, int> myhash;
inline int BSGS(int a, int b, int p) {
a %= p, b %= p;
if(p == 1 || b == 1) return 0;
int cnt = 0; LL tmp = 1; //tmp存a累计下来的系数
for(int g = gcd(a, p); g != 1; g = gcd(a, p)) {
if(b % g) return -1;
p /= g, b /= g; tmp = tmp * (a / g) % p, ++cnt;
if(b == tmp) return cnt;
}
myhash.clear();
int m = int(sqrt(p) + 1);
LL base = b;
for(int i = 0; i < m; ++i)
myhash[base] = i, base = base * a % p;
base = qpow(a, m, p);
LL now = tmp;
for(int i = 1; i <= m+1; ++i) {
now = now * base % p;
if(myhash.count(now))
return i * m - myhash[now] + cnt;
}
return -1; //仍然无解
}
int main() {
while(~scanf("%d%d%d", &p, &a, &b)) {
int ans = BSGS(a, b, p);
if(~ans) printf("%d
", ans);
else puts("no solution");
}
}