// Semi-Puzzle: Brain Storm // Module Version 230418 // Powered by GreatLiangpi #ifdef ONLINE_JUDGE #define TEST 1 // Test Switch #else // #define TEST 1 #define LOCAL 1 // Debug Switch #endif #ifndef LOCAL #define TEST 1 #endif #include<bits/stdc++.h> #define int int64_t #ifdef TEST #pragma GCC optimize(3, "Ofast", "inline") // Optimization Switch #define endl '\n' #endif #ifdef LOCAL #define endl " **\n" #endif #define tomax(x, y) x = max(x, (y)) #define tomin(x, y) x = min(x, (y)) usingnamespace std; #ifdef TEST constint MAX = 200005; #else #ifdef LOCAL constint MAX = 105; #endif #endif constint INF = 0x3f3f3f3f3f3f3f3fll; constint MOD = 1000000007; int call_count = 0;
namespace Prime_Tests { // 快速幂, 该快速幂使用 mod intquick_pow(__int128_t b, int e, int m){ __int128_t res = 1 % m; b = b % m; while (e) { if (e & 1) res = res * b % m; b = b * b % m; e >>= 1; } return res; }
// Miller Rabin 素性测试 // 154590409516822759, 2305843009213693951, 4384957924686954497 int test[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 79, 83, 89, 97, 233, }; // 测试集: 优先使用小质数 boolMiller_Rabin(int n){ if (n < 2or n > 2and n % 2 == 0) returnfalse; int s = n - 1; while (not(s & 1)) s >>= 1; for (int p : test) { if (n == p) returntrue; __int128_t t = s, m = quick_pow(p, s, n); while (t != n - 1and m != 1and m != n - 1) { m = m * m % n; t <<= 1; } if (m != n - 1andnot(t & 1)) returnfalse; } returntrue; }
// 随机数生成器 mt19937 rnd((unsignedint)chrono::steady_clock::now().time_since_epoch().count()); intrandint(int l, int r = 0){ if (l > r) swap(l, r); returnrnd() % (r - l + 1) + l; }
// Pollard Rho 因数测试 intPollard_Rho(int n){ if (n % 2 == 0) // Pollard 不能判 4 return2; if (Miller_Rabin(n)) return n; while (true) { int c = randint(1, n - 1); auto nxt = [&](__int128_t x) -> int { return (x * x + c) % n; }; int turtle = 1, rabbit = -1; __int128_t mul = 1; while (turtle != rabbit) { for (int i = 0; i < 128; i++) { turtle = nxt(turtle); rabbit = nxt(nxt(rabbit)); __int128_t tmp = mul * abs(turtle - rabbit) % n; // 龟兔相遇或积将为 0 退出 if (turtle == rabbit or tmp == 0) break; mul = tmp; } int g = __gcd((int)mul, n); if (g > 1) return g; } } }
// 使用 Pollard Rho 的分解质因数 int divisors[128]; intprime_divisors(int x){ int cnt = 0, p = 0; divisors[cnt++] = x; while (p < cnt) { int x = divisors[p]; int tmp = Pollard_Rho(x); if (tmp == x) { p++; } else { divisors[p] = tmp; divisors[cnt++] = x / tmp; } } sort(divisors, divisors + cnt); cnt = unique(divisors, divisors + cnt) - divisors; return cnt; } }
// 使用 Pollard Rho 的欧拉函数 inteuler(int x){ if (x < 2) return0; int cnt = Prime_Tests::prime_divisors(x); int res = x; for (int i = 0; i < cnt; i++) { int p = Prime_Tests::divisors[i]; res = res / p * (p - 1); } return res; }
// 快速幂, 该快速幂使用 exmod intquick_pow(__int128_t b, int e, int m){ __int128_t res = exmod(1, m); b = exmod(b, m); while (e) { if (e & 1) res = exmod(res * b, m); b = exmod(b * b, m); e >>= 1; } return res; }
// 计算幂塔 intcalc(int a, int m){ if (m == 1) returnexmod(a, m); returnquick_pow(a, calc(a, euler(m)), m); }
voidsolve(){ int a, m; cin >> a >> m; int phi = euler(m); int lcm = m / __gcd(m, phi) * phi; int res = calc(a, lcm); if (Prime_Tests::quick_pow(a, res % lcm, m) == res % lcm % m) { cout << res % lcm << endl; } else { cout << res << endl; } }