BZOJ2480 Spoj3105 Mod

乍一看题面:$$a^x equiv b (mod m)$$

是一道BSGS,但是很可惜$m$不是质数,而且$(m, a) ot= 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 ot 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
", 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 }
View Code
原文地址:https://www.cnblogs.com/rausen/p/4512167.html