Solution
\(POJ\) 跑的太快了!
我们用 \(hash\) 优化。选择一个让你心动的模数,把它像前向星一样存起来就行了。
Code
//#include <map>
#include <cmath>
#include <cstdio>
#include <cstring>
typedef long long ll;
//using namespace std;
//#if(__cplusplus == 201103L)
//#include <unordered_map>
//#else
//#include <tr1/unordered_map>
//namespace std {using std::tr1::unordered_map;}
//#endif
const int p = 1e7, N = 1e5;
//map <int, int> mp;
int mod, a, b, ans;
int cnt, head[p], from[N], to[N], nxt[N];
int read() {
int x = 0, f = 1; char s;
while((s = getchar()) > '9' || s < '0') if(s == '-') f = -1;
while(s >= '0' && s <= '9') x = (x << 1) + (x << 3) + (s ^ 48), s = getchar();
return x * f;
}
int gcd(const int x, const int y) {return !y ? x : gcd(y, x % y);}
int qkpow(int x, int y) {
int r = 1;
while(y) {
if(y & 1) r = 1ll * r * x % mod;
x = 1ll * x * x % mod; y >>= 1;
}
return r;
}
void Insert(const int x, const int y) {
int k = x % p; ++ cnt;
from[cnt] = x, to[cnt] = y;
nxt[cnt] = head[k], head[k] = cnt;
}
int Find(const int x) {
int k = x % p;
for(int i = head[k]; ~i; i = nxt[i])
if(from[i] == x) return to[i];
return -1;
}
int exBSGS() {
if(b == 1) return 0;
if(a % mod == 0) return 0;
//mp.clear();
memset(head, -1, sizeof head); cnt = 0;
int cnt = 0, t = 1, s, x, m;
for(int d = gcd(a, mod); d != 1; d = gcd(a, mod)) {
if(b % d) return -1;
++ cnt; b /= d, mod /= d; t = 1ll * t * a / d % mod;
if(b == t) return cnt;
}
s = b, m = ceil(sqrt(mod));
for(int i = 0; i <= m; ++ i) Insert(s, i), s = 1ll * s * a % mod;
x = qkpow(a, m), s = t;
for(int i = 1; i <= m; ++ i) {
s = 1ll * s * x % mod;
int r = Find(s);
if(r != -1) return i * m - r + cnt;
}
return -1;
}
int main() {
while(1) {
a = read(), mod = read(), b = read();
if(a + mod + b == 0) break;
a %= mod, b %= mod;
ans = exBSGS();
if(ans < 0) puts("No Solution");
else printf("%d\n", ans);
}
return 0;
}