結果

問題 No.187 中華風 (Hard)
ユーザー tkmst201
提出日時 2020-07-25 14:35:22
言語 C++14
(gcc 13.3.0 + boost 1.87.0)
結果
RE  
実行時間 -
コード長 2,369 bytes
コンパイル時間 442 ms
コンパイル使用メモリ 52,724 KB
実行使用メモリ 6,944 KB
最終ジャッジ日時 2024-06-27 05:40:28
合計ジャッジ時間 4,340 ms
ジャッジサーバーID
(参考情報)
judge2 / judge3
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 23 RE * 2
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#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));
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0