結果
| 問題 |
No.187 中華風 (Hard)
|
| コンテスト | |
| ユーザー |
ate
|
| 提出日時 | 2020-09-11 06:28:47 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 3,799 bytes |
| コンパイル時間 | 2,508 ms |
| コンパイル使用メモリ | 206,576 KB |
| 最終ジャッジ日時 | 2025-01-14 09:29:30 |
|
ジャッジサーバーID (参考情報) |
judge3 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 22 WA * 3 |
ソースコード
#include<tuple>
#include<cstdint>
template<class T = int64_t>
constexpr inline T mod(T a,T m){
a %= m;
return (a<0?a+m:a);
}
template<class T = int64_t>
std::tuple<T,T,T> ext_gcd(T a,T b){
if(b==0){
return {a,1,0};
}
auto [d,y,x] = ext_gcd(b,a%b);
y -= a/b * x;
return {d,x,y};
}
template<class T = int64_t>
T mod_inv(T a,T m){
auto[d,x,y] = ext_gcd(a,m);
return (d!=1?-1:mod(x,m));
}
#include<vector>
#include<cassert>
template<class T = int64_t>
T gerner(std::vector<T> const& b,std::vector<T> const& m){
assert(0<std::size(b));
assert(std::size(b)==std::size(m));
T prod_m = 1;
T x = b[0]%m[0];
for(int i=1;i<std::size(b);++i){
prod_m *= m[i-1];
T mij = mod_inv(prod_m,m[i]);
T t = mod((b[i]-x)*mij,m[i]);
x += t*prod_m;
}
return x;
}
int64_t gerner (std::vector<int64_t> b,std::vector<int64_t> m,int64_t const MOD){
using i64 = int64_t;
assert(0<std::size(b));
assert(std::size(b)==std::size(m));
m.emplace_back(MOD);
std::vector<i64> coeffs(std::size(m),1);
std::vector<i64> constants(std::size(m),0);
for(int k=0;k<std::size(b);++k){
i64 m_inv = mod_inv(coeffs[k],m[k]);
i64 t = mod((b[k]-constants[k])*m_inv,m[k]);
for(int i=k+1;i<std::size(m);++i){
(constants[i] += t*coeffs[i]) %= m[i];
(coeffs[i] *= m[k]) %= m[i];
}
}
return constants.back();
}
#include<bits/stdc++.h>
int64_t operator"" _i64(unsigned long long x){
return (int64_t)x;
}
void solve_yuki_187(){
using namespace std;
using i64 = int64_t;
constexpr i64 MOD = 1e9+7;
int n;
cin>>n;
vector<i64> x(n),y(n);
for(int i=0;i<n;++i)cin>>x[i]>>y[i];
// A % y[i] = x[i], A \equiv x[i] (mod. y[i])
{
// x[i] がすべて0なら lcm(y) が答え
if(all_of(begin(x),end(x),[](i64 xi){return xi==0;})){
auto acc_lcm = [&MOD](i64 acc,i64 yi){return lcm(acc,yi)%MOD;};
i64 ans = accumulate(begin(y),end(y),1_i64,acc_lcm);
cout<< ans <<endl;
return;
}
// 対ごとに素にできなかったら不可能
bool pairwise_coprime = true;
for(int l=0;l+1<n;++l)
for(int r=l+1;r<n;++r)
pairwise_coprime &= ((x[l]-x[r])%gcd(y[l],y[r])==0);
if(!pairwise_coprime){
cout<< -1 <<endl;
return;
}
}
{
// 対ごとに素にする
// m0 = 2**p0 + 3**p1 + 5**p2 + 7**p3
// m1 = 2**q0 + 3**q1 + 5**q2 + 7**q3
// のように具体的に値を割り振って計算すると指数の大きいほうが残って小さいほうが0になるのがわかる
for(int i=0;i+i<n;++i){
for(int j=i+1;j<n;++j){
i64& m0 = y[i];
i64& m1 = y[j];
i64 d = gcd(m0,m1);
i64 u0 = m0/d;
i64 u1 = m1/d;
i64 di = gcd(u0,d);
i64 dj = d/di;
do{
d = gcd(di,dj);
di *= d;
dj /= d;
}while(d!=1);
m0 = u0*di;
m1 = u1*dj;
x[i] %= y[i];
x[j] %= y[j];
}
}
}
i64 ans = gerner(x,y,MOD);
cout<< ans <<endl;
}
int main(){
solve_yuki_187();
}
void solve1(){
using namespace std;
using i64 = int64_t;
vector<i64> pairwise_coprime = {7,11,13,16,17,19,23,25,27,29};
auto contain = [&pairwise_coprime](int b_1){return binary_search(begin(pairwise_coprime),end(pairwise_coprime),b_1);};
vector<i64> a(31),r,m=pairwise_coprime;
for(int b=2;b<=30;++b){
cin>>a[b];
if(contain(b-1))
r.emplace_back(a[b]%(b-1));
}
i64 ans = gerner(r,m);
if(ans==25)exit(1);
auto invalid = [](){
cout<<"invalid"<<endl;
exit(0);
};
auto digit_sum = [](i64 x,i64 b){
i64 sum = 0;
while(x){
sum += x%b;
x /= b;
}
return sum;
};
if(ans>1e12)invalid();
for(int b=2;b<=30;++b)
if(a[b] != digit_sum(ans,b))
invalid();
cout<<ans<<endl;
}
ate