結果
問題 | No.981 一般冪乗根 |
ユーザー | risujiroh |
提出日時 | 2020-02-07 22:29:53 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
RE
|
実行時間 | - |
コード長 | 2,176 bytes |
コンパイル時間 | 1,803 ms |
コンパイル使用メモリ | 181,316 KB |
実行使用メモリ | 11,684 KB |
最終ジャッジ日時 | 2024-10-09 14:40:22 |
合計ジャッジ時間 | 37,220 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | RE | - |
testcase_01 | RE | - |
testcase_02 | RE | - |
testcase_03 | RE | - |
testcase_04 | RE | - |
testcase_05 | RE | - |
testcase_06 | RE | - |
testcase_07 | RE | - |
testcase_08 | RE | - |
testcase_09 | RE | - |
testcase_10 | RE | - |
testcase_11 | RE | - |
testcase_12 | RE | - |
testcase_13 | RE | - |
testcase_14 | RE | - |
testcase_15 | RE | - |
testcase_16 | RE | - |
testcase_17 | RE | - |
testcase_18 | RE | - |
testcase_19 | RE | - |
testcase_20 | RE | - |
testcase_21 | RE | - |
testcase_22 | RE | - |
testcase_23 | RE | - |
testcase_24 | RE | - |
testcase_25 | RE | - |
testcase_26 | RE | - |
testcase_27 | RE | - |
testcase_28 | TLE | - |
evil_60bit1.txt | -- | - |
evil_60bit2.txt | -- | - |
evil_60bit3.txt | -- | - |
evil_hack | -- | - |
evil_hard_random | -- | - |
evil_hard_safeprime.txt | -- | - |
evil_hard_tonelli0 | -- | - |
evil_hard_tonelli1 | -- | - |
evil_hard_tonelli2 | -- | - |
evil_hard_tonelli3 | -- | - |
evil_sefeprime1.txt | -- | - |
evil_sefeprime2.txt | -- | - |
evil_sefeprime3.txt | -- | - |
evil_tonelli1.txt | -- | - |
evil_tonelli2.txt | -- | - |
ソースコード
#include <bits/stdc++.h> using namespace std; using lint = long long; template<class Z> Z ext_gcd(Z a, Z b, Z& x, Z& y) { Z u = y = 0, v = x = 1; while (b) { Z q = a / b; swap(a -= q * b, b); swap(x -= q * u, u); swap(y -= q * v, v); } return a; } lint tmod(lint a, lint p) { return (a %= p) < 0 ? a + p : a; } lint mod_inv(lint a, lint p) { a = tmod(a, p); lint b = p, x = 1, u = 0; while (b) { lint q = a / b; swap(a -= q * b, b); swap(x -= q * u, u); } return a == 1 ? tmod(x, p) : -1; } lint mod_pow(lint a, lint n, lint p) { assert(n >= 0); a = tmod(a, p); lint res = 1; while (n) { if (n & 1) (res *= a) %= p; (a *= a) %= p; n >>= 1; } return res; } lint mod_log(lint g, lint x, lint p) { g = tmod(g, p); x = tmod(x, p); int m = ceil(sqrt(p - 1)); map<int, int> mp; lint a = 1; for (int j = 0; j < m; ++j) { mp[a] = j; (a *= g) %= p; } g = mod_inv(mod_pow(g, m, p), p), a = 1; for (int i = 0; i < (p - 1 + m - 1) / m; ++i) { if (mp.count(a * x % p)) { return i * m + mp[a * x % p]; } (a *= g) %= p; } return -1; } int mod_root(lint a, lint n, int p, int g) { a = tmod(a, p); if (a == 0) { return n > 0 ? 0 : -1; } n = tmod(n, p - 1); int e = mod_log(g, a, p); assert(e != -1); lint x, y; int d = ext_gcd<lint>(n, p - 1, x, y); if (e % d) return -1; return mod_pow(g, e / d * x + p - 1, p); } template<class Z> map<Z, int> factorize(Z n) { map<Z, int> res; for (Z i = 2; i * i <= n; ++i) while (n % i == 0) ++res[i], n /= i; if (n != 1) ++res[n]; return res; } int main() { int t; cin >> t; while (t--) { lint p, k, a; cin >> p >> k >> a; auto mp = factorize(p - 1); auto mod_ord = [&](lint x) -> lint { if (mod_pow(x, p - 1, p) != 1) return -1; lint res = p - 1; for (const auto& e : mp) { for (int i = 0; i < e.second; ++i) { if (mod_pow(x, res / e.first, p) == 1) { res /= e.first; } else break; } } return res; }; lint g = 1; while (mod_ord(g) != p - 1) { ++g; } cout << mod_root(a, k, p, g) << '\n'; } }