結果
問題 | No.187 中華風 (Hard) |
ユーザー |
![]() |
提出日時 | 2020-07-25 14:36:07 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 211 ms / 3,000 ms |
コード長 | 2,370 bytes |
コンパイル時間 | 490 ms |
コンパイル使用メモリ | 52,580 KB |
実行使用メモリ | 6,944 KB |
最終ジャッジ日時 | 2024-06-27 05:41:36 |
合計ジャッジ時間 | 4,156 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 25 |
ソースコード
#include <vector>#include <cassert>#include <cstdio>struct Garner {public:using size_type = std::size_t;template<typename T>static bool preprocess(std::vector<T> &b, std::vector<T> &m) {for (size_type i = 0; i < b.size(); ++i) {for (size_type j = 0; j < i; ++j) {T g = gcd(m[i], m[j]);if ((b[i] - b[j]) % g) return false;m[i] /= g; m[j] /= g;T gi = gcd(g, m[i]), gj = g / gi;do {g = gcd(gi, gj);gi *= g; gj /= g;} while (g != 1);m[i] *= gi; m[j] *= gj;b[i] %= m[i]; b[j] %= m[j];}}return true;}template<typename T>static T garner(const std::vector<T> &b, std::vector<T> m, const T mod) {assert(b.size() == m.size());assert(!b.empty());T tg = m[0];for (size_type i = 0; i < b.size(); ++i) {assert(m[i] > 0);tg = gcd(tg, m[i]);}assert(mod > 0);assert(b.size() == 1 || tg == 1);m.emplace_back(mod);std::vector<T> sum(m.size()), ip(m.size(), 1);for (size_type i = 0; i < b.size(); ++i) {/*ip[j] := m_0 m_1 \ldots m_{i-1} (mod. m_j)sum[j] := t_0 ip[0] t_1 ip[1] \ldots t_{i-1} ip[i-1] (mod. m_j)*/T t = ((b[i] % m[i] + m[i]) % m[i] - sum[i] + m[i]) % m[i] % m[i] * inverse(ip[i], m[i]) % m[i];for (size_type j = i + 1; j < m.size(); ++j) {sum[j] = (sum[j] + ip[j] * t) % m[j];ip[j] = (ip[j] * m[i] % m[j]);}}return sum.back();}private:template<typename T>static T gcd(T a, T b) {while (b > 0) {T nb = a % b;a = b;b = nb;}return a;}template<typename T>static T inverse(const T &a, const T &mod) {T a0 = (a % mod + mod) % mod, a1 = 1, a2 = 0;T b0 = mod, b1 = 0, b2 = 1;while (b0 > 0) {T q = a0 / b0, r = a0 % b0;T nb0 = a0 % b0, nb1 = a1 - b1 * q, nb2 = a2 - b2 * q;a0 = b0; a1 = b1; a2 = b2;b0 = nb0; b1 = nb1; b2 = nb2;}assert(a0 == 1);return (a1 % mod + mod) % mod;}};#include <cstdio>int main() {int N;scanf("%d", &N);std::vector<long long> b(N), m(N);bool zero = true;for (int i = 0; i < N; ++i) scanf("%lld %lld", &b[i], &m[i]), zero &= b[i] == 0;constexpr long long mod = 1000000007;if (!Garner::preprocess(b, m)) puts("-1");else if (zero) {long long ans = 1;for (auto c : m) ans = ans * c % mod;printf("%lld\n", ans);}else printf("%lld\n", Garner::garner(b, m, mod));}