結果
問題 | No.187 中華風 (Hard) |
ユーザー | MarcusAureliusAntoninus |
提出日時 | 2019-10-08 14:44:35 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 271 ms / 3,000 ms |
コード長 | 2,665 bytes |
コンパイル時間 | 2,660 ms |
コンパイル使用メモリ | 214,588 KB |
実行使用メモリ | 5,248 KB |
最終ジャッジ日時 | 2024-11-07 00:21:06 |
合計ジャッジ時間 | 6,894 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 33 ms
5,248 KB |
testcase_01 | AC | 34 ms
5,248 KB |
testcase_02 | AC | 209 ms
5,248 KB |
testcase_03 | AC | 206 ms
5,248 KB |
testcase_04 | AC | 269 ms
5,248 KB |
testcase_05 | AC | 268 ms
5,248 KB |
testcase_06 | AC | 269 ms
5,248 KB |
testcase_07 | AC | 270 ms
5,248 KB |
testcase_08 | AC | 193 ms
5,248 KB |
testcase_09 | AC | 195 ms
5,248 KB |
testcase_10 | AC | 194 ms
5,248 KB |
testcase_11 | AC | 271 ms
5,248 KB |
testcase_12 | AC | 268 ms
5,248 KB |
testcase_13 | AC | 90 ms
5,248 KB |
testcase_14 | AC | 90 ms
5,248 KB |
testcase_15 | AC | 75 ms
5,248 KB |
testcase_16 | AC | 75 ms
5,248 KB |
testcase_17 | AC | 20 ms
5,248 KB |
testcase_18 | AC | 32 ms
5,248 KB |
testcase_19 | AC | 20 ms
5,248 KB |
testcase_20 | AC | 214 ms
5,248 KB |
testcase_21 | AC | 20 ms
5,248 KB |
testcase_22 | AC | 268 ms
5,248 KB |
testcase_23 | AC | 21 ms
5,248 KB |
testcase_24 | AC | 20 ms
5,248 KB |
ソースコード
#include <bits/stdc++.h> int64_t calcGCD(int64_t a, int64_t b) { while (a) { b %= a; std::swap(a, b); } return b; } //////////////////////////// // 拡張ユークリッドの互除法 // //////////////////////////// // x, yは非負整数 // ret[0] * x + ret[1] * y == ret[2] == gcd(x, y) となるようなretを返す std::array<int64_t, 3> extendedEuclidean(const int64_t x, const int64_t y) { if (y == 0) return {1, 0, x}; auto next{extendedEuclidean(y, x % y)}; return {next[1], next[0] - (x / y) * next[1], next[2]}; } ///////////////////////// // Garnerのアルゴリズム // ///////////////////////// int64_t garner(const std::vector<int64_t>& rests, const std::vector<int64_t>& mods, const int64_t ans_mod) { std::vector<int64_t> coefficient(rests); for (int i{}; i < (int)rests.size(); i++) { int64_t mod_multi{1ll}; for (int j{}; j < i; j++) { coefficient[i] = (coefficient[i] + mods[i] - mod_multi * coefficient[j] % mods[i]) % mods[i]; mod_multi = mod_multi * mods[j] % mods[i]; } for (int j{}; j < i; j++) coefficient[i] = coefficient[i] * ((extendedEuclidean(mods[j], mods[i])[0] + mods[i]) % mods[i]) % mods[i]; } int64_t ret{}, mod_multi{1ll}; for (int i{}; i < (int)rests.size(); i++) { ret = (ret + mod_multi * coefficient[i] % ans_mod) % ans_mod; mod_multi = mod_multi * mods[i] % ans_mod; } return ret; } int main() { using namespace std; using ll = int64_t; int n; cin >> n; vector<ll> vs(n), ms(n); for (int i = 0; i < n; i++) { cin >> vs[i] >> ms[i]; } vector<int> primes; for (int i = 2; (ll)i * i <= 1e9; i++) { int flag = 1; for (int x : primes) if (i % x == 0) { flag = 0; break; } if (flag) primes.emplace_back(i); } for (int m : ms) { for (int p : primes) while (m % p == 0) m /= p; if (m != 1) primes.emplace_back(m); } for (int p : primes) { vector<pair<int, int>> ps; for (int i = 0; i < n; i++) { if (ms[i] % p == 0) { int lg = 0; while (ms[i] % p == 0) ms[i] /= p, lg++; ps.emplace_back(lg, i); } } if (ps.size() < 1) continue; sort(begin(ps), end(ps)); int base = vs[ps.back().second]; for (auto d : ps) { if (vs[d.second] % p != base % p) { cout << -1 << endl; return 0; } if (d.second == ps.back().second) { for (int i = 0; i < d.first; i++) ms[d.second] *= p; } } } int allzero = 1; ll ans = 1; for (int i = 0; i < n; i++) { vs[i] = vs[i] % ms[i]; if (vs[i] != 0) allzero = 0; ans = ans * ms[i] % int(1e9 + 7); } if (allzero) { cout << ans << endl; return 0; } cout << garner(vs, ms, 1e9 + 7) << endl; }