結果

問題 No.187 中華風 (Hard)
ユーザー kyunakyuna
提出日時 2020-02-07 03:52:03
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 201 ms / 3,000 ms
コード長 2,079 bytes
コンパイル時間 658 ms
コンパイル使用メモリ 75,640 KB
実行使用メモリ 4,348 KB
最終ジャッジ日時 2023-10-25 22:58:07
合計ジャッジ時間 4,391 ms
ジャッジサーバーID
(参考情報)
judge15 / judge13
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,348 KB
testcase_01 AC 2 ms
4,348 KB
testcase_02 AC 161 ms
4,348 KB
testcase_03 AC 154 ms
4,348 KB
testcase_04 AC 200 ms
4,348 KB
testcase_05 AC 199 ms
4,348 KB
testcase_06 AC 200 ms
4,348 KB
testcase_07 AC 201 ms
4,348 KB
testcase_08 AC 141 ms
4,348 KB
testcase_09 AC 141 ms
4,348 KB
testcase_10 AC 141 ms
4,348 KB
testcase_11 AC 201 ms
4,348 KB
testcase_12 AC 201 ms
4,348 KB
testcase_13 AC 58 ms
4,348 KB
testcase_14 AC 58 ms
4,348 KB
testcase_15 AC 143 ms
4,348 KB
testcase_16 AC 146 ms
4,348 KB
testcase_17 AC 2 ms
4,348 KB
testcase_18 AC 2 ms
4,348 KB
testcase_19 AC 2 ms
4,348 KB
testcase_20 AC 153 ms
4,348 KB
testcase_21 AC 2 ms
4,348 KB
testcase_22 AC 200 ms
4,348 KB
testcase_23 AC 1 ms
4,348 KB
testcase_24 AC 2 ms
4,348 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
const int MOD = (int)1e9 + 7;
inline long long gcd(long long a, long long b) { return b ? gcd(b, a % b) : a; }

long long extgcd(long long a, long long b, long long &x, long long &y) {
    for (long long u = y = 1, v = x = 0; a; ) {
        long long q = b / a;
        swap(x -= q * u, u);
        swap(y -= q * v, v);
        swap(b -= q * a, a);
    }
    return b;
}

long long modinv(long long a, long long m) {
    long long x, y;
    extgcd(a, m, x, y);
    return (x + m) % m;
}

long long pre_garner(vector<long long> &b, vector<long long> &m, long long mod) {
    long long res = 1;
    for (int i = 0; i < (int)b.size(); i++) for (int j = 0; j < i; j++) {
        long long g = gcd(m[i], m[j]);
        if ((b[i] - b[j]) % g != 0) return -1;
        m[i] /= g, m[j] /= g;
        long long gi = gcd(m[i], g), gj = g / gi;
        while ((g = gcd(gi, gj)) != 1) gi *= g, gj /= g;
        m[i] *= gi, m[j] *= gj;
        b[i] %= m[i], b[j] %= m[j];
    }
    for (int i = 0; i < (int)b.size(); i++) (res *= m[i]) %= mod;
    return res;
}

long long garner(vector<long long> b, vector<long long> m, long long mod) {
    m.push_back(mod);   // sentinel
    vector<long long> coeffs((int)m.size(), 1);
    vector<long long> constants((int)m.size(), 0);
    for (int k = 0; k < (int)b.size(); k++) {
        long long a = (b[k] - constants[k]) * modinv(coeffs[k], m[k]);
        long long t = (a % m[k] + m[k]) % m[k];
        for (int i = k + 1; i < (int)m.size(); i++) {
            (constants[i] += t * coeffs[i]) %= m[i];
            (coeffs[i] *= m[k]) %= m[i];
        }
    }
    return constants.back();
}

int main() {
    int n; cin >> n;
    vector<long long> b(n), m(n);
    bool exist_non_zero = false;
    for (int i = 0; i < n; i++) {
        cin >> b[i] >> m[i];
        if (b[i]) exist_non_zero = true;
    }
    long long lcm = pre_garner(b, m, MOD);
    if (!exist_non_zero || lcm == -1) return !(cout << lcm << endl);
    cout << garner(b, m, MOD) << endl;
    return 0;
}
0