乍一看题面:$$a^x \equiv b \ (mod \ m)$$
是一道BSGS,但是很可惜$m$不是质数,而且$(m, a) \not= 1$,这个叫扩展BSGS【额......
于是我们需要通过变换使得$(m, a) = 1$
首先令$g = (a, m)$,则原式等价于:$$a ^ x + k * m = b, k \in \mathbb{Z}$$
移项可得:$$\frac{a} {g} * a ^ {x - 1} + k * \frac {m} {g} = \frac {b} {g}$$
此时如果$b \not \equiv 0 (mod\ g)$则无解
令$m' = \frac {m} {g}, b' = \frac {b} {g} * (\frac{a} {g}) ^ {-1}$
于是得到新式:$$a ^ {x - 1} = b' (mod\ m')$$
于是可以一直迭代到$(m, a) = 1$,然后用BSGS来计算答案即可
1 /************************************************************** 2 Problem: 2480 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:3256 ms 7 Memory:1568 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <algorithm> 12 #include <ext/pb_ds/assoc_container.hpp> 13 #include <ext/pb_ds/hash_policy.hpp> 14 15 using namespace std; 16 using namespace std; 17 typedef long long ll; 18 typedef __gnu_pbds::cc_hash_table <int, int> hash; 19 20 inline int read(); 21 22 int a, b, m, ans; 23 hash h; 24 25 inline int pow(ll x, ll y, ll mod) { 26 static ll res; 27 res = 1; 28 while (y) { 29 if (y & 1) res = res * x % mod; 30 x = x * x % mod, y >>= 1; 31 } 32 return (int) res; 33 } 34 35 inline int BSGS(int a, int b, int p, ll now) { 36 static int m, i; 37 static ll base; 38 m = (int) ceil(sqrt(p)), base = b; 39 h.clear(); 40 for (i = 0; i < m; ++i) 41 h[base] = i, base = base * a % p; 42 43 base = pow(a, m, p); 44 for (i = 1; i <= m + 1; ++i) { 45 now = now * base % p; 46 if (h.find(now) != h.end()) return i * m - h[now]; 47 } 48 return -1; 49 } 50 51 int extend_BSGS(int a, int b, int m) { 52 static int cnt, g, res; 53 static ll t; 54 a %= m, b %= m; 55 if (b == 1) return 0; 56 cnt = 0, g = __gcd(a, m), t = 1; 57 while (g != 1) { 58 if (b % g) return -1; 59 m /= g, b /= g, t = t * a / g % m; 60 ++cnt; 61 if (b == t) return cnt; 62 g = __gcd(a, m); 63 } 64 res = BSGS(a, b, m, t); 65 return ~res ? res + cnt : res; 66 } 67 68 int main() { 69 while (1) { 70 a = read(), m = read(), b = read(); 71 if (!a && !m && !b) return 0; 72 ans = extend_BSGS(a, b, m); 73 if (!~ans) puts("No Solution"); 74 else printf("%d\n", ans); 75 } 76 return 0; 77 } 78 79 inline int read() { 80 static int x; 81 static char ch; 82 x = 0, ch = getchar(); 83 while (ch < '0' || '9' < ch) 84 ch = getchar(); 85 while ('0' <= ch && ch <= '9') { 86 x = x * 10 + ch - '0'; 87 ch = getchar(); 88 } 89 return x; 90 }
By Xs酱~ 转载请说明
博客地址:http://www.cnblogs.com/rausen