結果
| 問題 |
No.186 中華風 (Easy)
|
| コンテスト | |
| ユーザー |
東前頭十一枚目
|
| 提出日時 | 2019-09-26 13:50:05 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 3 ms / 2,000 ms |
| コード長 | 2,040 bytes |
| コンパイル時間 | 1,857 ms |
| コンパイル使用メモリ | 169,040 KB |
| 実行使用メモリ | 5,376 KB |
| 最終ジャッジ日時 | 2024-07-19 18:35:47 |
| 合計ジャッジ時間 | 2,914 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 23 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
template<typename T>
struct ChineseRemainderTheorem {
inline T modulo(T x, T mod) {
if(0 <= x and x < mod) return x;
x %= mod;
if(x < 0) x += mod;
return x;
}
// gcd(a, b)
// ap + bq = gcd(a, b)を満たす(p, q)
T exGCD(T a, T b, T &p, T &q) {
if(b == 0) {
// gcd(a, b)p + 0q = gcd(a, b)
p = 1, q = 0;
return a;
}
T ret = exGCD(b, a % b, q, p);
q -= a / b * p;
return ret;
}
// x ≡ b(mod m)を満たすx(mod M (= lcm m))
T get(vector<T> &b, vector<T> &mod) {
// x ≡ 0(mod 1)は全ての整数
T x = 0, MOD = 1;
for(int i = 0; i < (int)b.size(); ++i) {
T p, q;
T d = exGCD(MOD, mod[i], p, q);
// 必要十分性の確認
if((x - b[i]) % d != 0) throw "NOT FOUND";
// nextMOD = MOD * (mod[i] / d)なので部分的にmodが取れてオーバーフロー回避
x = x - modulo((x - b[i]) / d * p, (mod[i] / d)) * MOD;
// lcm(M, m) = M * m / gcd(M, m)
MOD = MOD * (mod[i] / d);
x = modulo(x, MOD);
}
return modulo(x, MOD);
}
T Garner(vector<T> &b, vector<T> &mod, T MOD = numeric_limits<T>::max()) {
// normalisation(b, mod);
vector<T> p(b.size());
for(int i = 0; i < (int)b.size(); ++i) {
p[i] = b[i] % mod[i];
for(int j = 0; j < i; ++j) {
T inv, _tmp;
exGCD(mod[j], mod[i], inv, _tmp);
inv = modulo(inv, mod[i]);
p[i] = (p[i] - p[j]) * inv;
p[i] = modulo(p[i], mod[i]);
}
}
// 復元
T ret = 0;
for(int i = 0; i < (int)b.size(); ++i) {
T tmp = modulo(p[i], MOD);
for(int j = 0; j < i; ++j) {
tmp *= mod[j];
tmp %= MOD;
}
ret += tmp;
ret %= MOD;
}
return ret;
}
};
int main() {
const int n = 3;
vector<int64_t> x(n), y(n);
for(int i = 0; i < n; ++i) {
cin >> x[i] >> y[i];
}
ChineseRemainderTheorem<int64_t> crt;
try {
int64_t ans = crt.get(x, y);
if(ans == 0) {
ans = 1;
for(int i = 0; i < n; ++i) {
ans = ans * y[i] / __gcd(ans, y[i]);
}
}
cout << ans << '\n';
}
catch(...) {
cout << -1 << '\n';
}
return 0;
}
東前頭十一枚目