結果
問題 | No.981 一般冪乗根 |
ユーザー |
![]() |
提出日時 | 2020-02-10 19:08:19 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 5,410 ms / 6,000 ms |
コード長 | 1,587 bytes |
コンパイル時間 | 2,685 ms |
コンパイル使用メモリ | 77,932 KB |
実行使用メモリ | 10,496 KB |
最終ジャッジ日時 | 2024-10-09 23:37:12 |
合計ジャッジ時間 | 187,264 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 30 TLE * 14 |
ソースコード
#include <vector>#include <iostream>#include <algorithm>using namespace std;int binpow(int a, int b, int mod) {int ans = 1;while (b > 0) {if (b & 1) ans = 1LL * ans * a % mod;a = 1LL * a * a % mod;b >>= 1;}return ans;}int find_primitive_root(int p) {// Time complexity: O(p^(1/4+eps))int x = p - 1;vector<int> checks;for (int i = 2; i * i <= x; ++i) {if (x % i == 0) {while (x % i == 0) x /= i;checks.push_back((p - 1) / i);}}if (x > 1) {checks.push_back((p - 1) / x);}for (int i = 2; i < p; ++i) {bool ok = true;for (int j : checks) {if (binpow(i, j, p) == 1) {ok = false;break;}}if (ok) return i;}return -1;}int main() {int Q;cin >> Q;while (Q--) {int P, K, A;cin >> P >> K >> A;int g = find_primitive_root(P);int b = binpow(g, K, P);int bucket = 0;while (bucket * bucket < P) {++bucket;}int mul = 1;vector<int> val(bucket), perm(bucket);for (int i = 0; i < bucket; ++i) {val[i] = mul;perm[i] = i;mul = 1LL * mul * b % P;}sort(perm.begin(), perm.end(), [&](int i, int j) { return val[i] < val[j]; });int pmul = 1, ans = -1;mul = binpow(mul, P - 2, P);for (int i = 0; i < bucket; ++i) {int target = 1LL * A * pmul % P;int l = 0, r = bucket;while (r - l > 1) {int m = (l + r) >> 1;if (val[perm[m]] <= target) l = m;else r = m;}if (val[perm[l]] == target) {ans = binpow(g, i * bucket + perm[l], P);break;}pmul = 1LL * pmul * mul % P;}cout << ans << '\n';}return 0;}