1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| int BSGS(int a, int b, int Mod) { if (b == 1 || Mod == 1) return 0; std::unordered_map<int, int> H; int cur = b, K = std::sqrt(Mod) + 1; for (int i = 0; i < K; ++ i, cur = (LL) cur * a % Mod) H[cur] = i; int ak = cur = qpow(a, K, Mod); for (int i = 1; i <= K; ++ i, cur = (LL) cur * ak % Mod) if (H.count(cur)) return i * K - H[cur]; return -1; }
int findrt(int p, int k) { int pk = qpow(p, k); std::vector<int> fac; int n = pk - 1; for (int i = 2; i <= n / i; ++ i) if (n % i == 0) { fac.push_back(i); while (n % i == 0) n /= i; } if (n ^ 1) fac.push_back(n); auto check = [&](int g) { for (int x : fac) if (qpow(g, pk / p * (p - 1) / x, pk) == 1) return false; return true; }; for (int i = 2; i < pk; ++ i) if (check(i)) return i; return -1; }
int solve(int a, int b, int p, int k) { int pk = qpow(p, k); b %= pk; if (b == 0) return qpow(p, k - (k + a - 1) / a); if (b % p == 0) { int t = 0; while (b % p == 0) b /= p, ++ t; if (t % a) return 0; return solve(a, b, p, k - t) * qpow(p, t - t / a); } int g = findrt(p, k), _b = BSGS(g, b, pk); if (_b % Gcd(a, pk / p * (p - 1))) return 0; return Gcd(a, pk / p * (p - 1)); }
void work() { int a, b, p, res = 1; scanf("%d %d %d", &a, &b, &p), p = 2 * p + 1; for (int i = 2; i <= p / i; ++ i) if (p % i == 0) { int t = 0; while (p % i == 0) ++ t, p /= i; res *= solve(a, b, i, t); } if (p ^ 1) res *= solve(a, b, p, 1); printf("%d\n", res); }
|
Gitalking ...