結果
問題 |
No.187 中華風 (Hard)
|
ユーザー |
|
提出日時 | 2025-06-07 04:50:34 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 288 ms / 3,000 ms |
コード長 | 5,293 bytes |
コンパイル時間 | 3,357 ms |
コンパイル使用メモリ | 279,076 KB |
実行使用メモリ | 7,844 KB |
最終ジャッジ日時 | 2025-06-07 04:50:44 |
合計ジャッジ時間 | 8,238 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 25 |
ソースコード
#include <bits/stdc++.h> using ll = long long; using u8 = uint8_t; using i32 = int32_t; using u32 = uint32_t; using i64 = int64_t; using u64 = uint64_t; using i128 = __int128_t; using u128 = __uint128_t; namespace internal { constexpr long long safe_mod(long long x, long long m) { x %= m; if (x < 0) x += m; return x; } constexpr long long pow_mod_constexpr(long long x, long long n, int m_) { if (m_ == 1) return 0; unsigned int m = static_cast<unsigned int>(m_); unsigned long long r = 1, y = safe_mod(x, m); while (n) { if (n & 1) { r = (r * y) % m; } y = (y * y) % m; n >>= 1; } return r; } constexpr bool is_prime_constexpr(int n) { if (n <= 1) return false; if (n == 2 || n == 7 || n == 61) return true; if (n % 2 == 0) return false; long long t = n - 1; while (t % 2 == 0) t /= 2; constexpr long long base[3] = {2, 7, 61}; for (long long a : base) { long long d = t; long long v = pow_mod_constexpr(a, t, n); if (v == 1) continue; while (d != n - 1 && v != n - 1) { v = v * v % n; d <<= 1; } if (v != n - 1 && d % 2 == 0) return false; } return true; } template <int n> constexpr bool is_prime = is_prime_constexpr(n); constexpr std::pair<long long, long long> inv_gcd(long long a, long long b) { a = safe_mod(a, b); if (a == 0) return {b, 0}; long long s = b, t = a; long long m0 = 0, m1 = 1; while (t) { long long u = s / t; s -= t * u; m0 -= m1 * u; auto tmp = s; s = t; t = tmp; tmp = m0; m0 = m1; m1 = tmp; } if (m0 < 0) m0 += b / s; return {s, m0}; } constexpr long long inv_mod(long long x, long long m) { assert(1 <= m); auto z = inv_gcd(x, m); assert(z.first == 1); return z.second; } constexpr int primitive_root_constexpr(int m) { if (m == 2) return 1; if (m == 167772161) return 3; if (m == 469762049) return 3; if (m == 754974721) return 11; if (m == 998244353) return 3; int divs[20] = {}; divs[0] = 2; int cnt = 1; int x = (m - 1) / 2; while (x % 2 == 0) x /= 2; for (int i = 3; i <= x / i; i += 2) { if (x % i == 0) { divs[cnt++] = i; while (x % i == 0) x /= i; } } if (x > 1) divs[cnt++] = x; for (int g = 2;; g++) { bool ok = true; for (int i = 0; i < cnt; i++) { if (pow_mod_constexpr(g, (m - 1) / divs[i], m) == 1) { ok = false; break; } } if (ok) return g; } } template <int m> constexpr int primitive_root = primitive_root_constexpr(m); unsigned long long floor_sum_unsigned(unsigned long long n, unsigned long long m, unsigned long long a, unsigned long long b) { unsigned long long ans = 0; while (true) { if (a >= m) { ans += n * (n - 1) / 2 * (a / m); a %= m; } if (b >= m) { ans += n * (b / m); b %= m; } unsigned long long y_max = a * n + b; if (y_max < m) break; n = (unsigned long long)(y_max / m); b = (unsigned long long)(y_max % m); std::swap(m, a); } return ans; } } // namespace internal template <class T> bool Prepare_Garner(std::vector<T>& a, std::vector<T>& p) { int n = a.size(); for (int i = 0; i < n; i++) { for (int j = 0; j < i; j++) { T g = std::gcd(p[i], p[j]); if ((a[j] - a[i]) % g != 0) return false; p[i] /= g, p[j] /= g; T gi = std::gcd(p[i], g); T gj = g / gi; do { int g = std::gcd(gi, gj); gi *= g, gj /= g; } while (std::gcd(gi, gj) != 1); p[i] *= gi, p[j] *= gj; a[i] %= p[i], a[j] %= p[j]; } } return true; } template <class U> std::vector<U> Garner(const std::vector<U>& a, const std::vector<U>& p) { assert(a.size() == p.size()); std::vector<U> x(a.size()); int n = a.size(); for (int i = 0; i < n; i++) { x[i] = a[i]; for (int j = 0; j < i; j++) { long long z = internal::inv_mod(p[j], p[i]) * (x[i] - x[j]); z = internal::safe_mod(z, p[i]); x[i] = z; } } return x; } int main() { int N; std::cin >> N; using namespace std; vector<long long> X(N), Y(N); for(int i = 0; i < N; i++) cin >> X[i] >> Y[i]; if (!Prepare_Garner(X, Y)) { cout << -1 << "\n"; return 0; } const int MOD = (int)1e9 + 7; auto T = Garner(X, Y); if (T == vector<long long>(T.size())) { ll ans = 1; for (int i = 0; i < T.size(); i++) ans = (ans * Y[i]) % MOD; cout << ans << endl; } else { ll prod = 1; ll ans = 0; for (int i = 0; i < T.size(); i++) { ans += T[i] * prod; prod *= Y[i]; ans %= MOD; prod %= MOD; } cout << ans << endl; } }