結果
問題 | No.2688 Cell Proliferation (Hard) |
ユーザー | pockyny |
提出日時 | 2024-04-14 14:18:14 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 1,574 ms / 4,000 ms |
コード長 | 7,362 bytes |
コンパイル時間 | 2,957 ms |
コンパイル使用メモリ | 140,544 KB |
実行使用メモリ | 55,364 KB |
最終ジャッジ日時 | 2024-10-03 13:11:54 |
合計ジャッジ時間 | 30,852 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 3 ms
5,248 KB |
testcase_02 | AC | 2 ms
5,248 KB |
testcase_03 | AC | 139 ms
9,520 KB |
testcase_04 | AC | 1,450 ms
53,752 KB |
testcase_05 | AC | 764 ms
29,260 KB |
testcase_06 | AC | 338 ms
16,028 KB |
testcase_07 | AC | 337 ms
15,940 KB |
testcase_08 | AC | 1,429 ms
52,528 KB |
testcase_09 | AC | 1,441 ms
51,884 KB |
testcase_10 | AC | 1,541 ms
54,072 KB |
testcase_11 | AC | 1,466 ms
53,032 KB |
testcase_12 | AC | 394 ms
16,876 KB |
testcase_13 | AC | 1,545 ms
55,364 KB |
testcase_14 | AC | 1,430 ms
50,072 KB |
testcase_15 | AC | 1,550 ms
55,344 KB |
testcase_16 | AC | 1,418 ms
49,720 KB |
testcase_17 | AC | 801 ms
30,432 KB |
testcase_18 | AC | 1,549 ms
54,192 KB |
testcase_19 | AC | 788 ms
30,568 KB |
testcase_20 | AC | 666 ms
26,976 KB |
testcase_21 | AC | 671 ms
26,876 KB |
testcase_22 | AC | 790 ms
30,124 KB |
testcase_23 | AC | 702 ms
27,504 KB |
testcase_24 | AC | 1,574 ms
53,960 KB |
testcase_25 | AC | 463 ms
17,096 KB |
testcase_26 | AC | 1,558 ms
54,468 KB |
testcase_27 | AC | 834 ms
30,624 KB |
testcase_28 | AC | 1,457 ms
49,836 KB |
ソースコード
#pragma GCC target("avx2") #pragma GCC optimize("O3") #pragma GCC optimize("unroll-loops") #include <iostream> #include <vector> #include <cassert> #include <atcoder/modint> #include <atcoder/convolution> using namespace std; using namespace atcoder; using mint = modint998244353; // verify: https://judge.yosupo.jp/submission/153840 vector<mint> fps_inv(vector<mint> f,int deg = -1){ if(deg==-1) deg = f.size() - 1; assert(f.size()); assert(f[0].val()!=0); vector<mint> g = {(mint)1/f[0]}; for(int i=1;i<=deg;i<<=1){ vector<mint> h = convolution(g,f); h.resize(2*i); for(mint &u:h) u = -u; h[0] += 2; g = convolution(g,h); g.resize(2*i); } g.resize(deg + 1); return g; } // vector<mint> fps_derivative(vector<mint> &f){ // vector<mint> ret; // for(int i=1;i<f.size();i++){ // ret.push_back(f[i]*i); // } // if(f.size()==1) ret.push_back(0); // return ret; // } // // get integral f(x) dx, s.t. const = 0; // vector<mint> fps_integral(vector<mint> &f){ // vector<mint> g(f.size()); // for(int i=g.size() - 1;i>=1;i--){ // g[i] = f[i - 1]/(mint)(i); // } // g[0] = 0; // return g; // } // // get log(f) = -sum (1 - f)^n/n // vector<mint> fps_log(vector<mint> f,int deg = -1){ // if(deg==-1) deg = f.size() - 1; // assert(f[0].val()==1); // vector<mint> g = convolution(fps_derivative(f),fps_inv(f,deg)); // g.resize(deg + 1); // return fps_integral(g); // } // // get exp(f) = sum f^i/i! // vector<mint> fps_exp(vector<mint> f,int deg = -1){ // if(deg==-1) deg = f.size() - 1; // assert(f.size()); // assert(f[0].val()==0); // vector<mint> g = {(mint)1}; // for(int i=1;i<=deg;i<<=1){ // vector<mint> h(2*i); // h[0] = 1; // vector<mint> log_g = fps_log(g,h.size() - 1); // for(int j=0;j<h.size();j++) h[j] -= log_g[j]; // for(int j=0;j<min(f.size(),h.size());j++) h[j] += f[j]; // g = convolution(g,h); // g.resize(2*i); // } // g.resize(deg + 1); // return g; // } // using ll = long long; // const int MX = 1000010; // mint f[MX],inv[MX],fi[MX]; // constexpr ll mod = 998244353; // void solve(){ // inv[1] = 1; // for(int i=2;i<MX;i++){ // inv[i] = mod - (mod/i)*inv[mod%i]; // } // f[0] = fi[0] = 1; // for(int i=1;i<MX;i++){ // f[i] = f[i-1]*i; // fi[i] = fi[i-1]*inv[i]; // } // } // // input f(x) output g(x) = f(x + d) // // 階乗の逆元の計算が必須 // vector<mint> shift(vector<mint> ff,int d){ // int i,len = ff.size(); // vector<mint> f1(len + 1),f2(len + 1); // mint x = 1; // for(i=0;i<len;i++){ // f1[i] = ff[i]*f[i]; // f2[len - i] = x*fi[i]; // x *= d; // } // vector<mint> f3 = convolution(f1,f2); // vector<mint> ret; // for(i=len;i<2*len;i++){ // ret.push_back(f3[i]*fi[i - len]); // } // return ret; // } // // input: s[0] + s[1]x + ... s[n - 1]x^n - 1 // // output: (c[0] - c[1] - .. c[d])s = 0かつc[0] = 1なるcを存在すればどれか一つ // // copied from: https://nyaannyaan.github.io/library/fps/berlekamp-massey.hpp // // verified: https://judge.yosupo.jp/submission/199848 // // algorithmの気持ち // // deg(c) = kの時に s[i] + Σ_{j<k} c[j]*s[i - 1 - j] を計算する // // 0ならOKで、0じゃないときは、1個前のcの線形結合で補正項を入れる // // 今までは成功していてたので、1個前のcの線形結合で補正したら、自分より下はつじつまが合うし、補正を入れるので徐々にあっていく // template <typename mint> // vector<mint> BerlekampMassey(const vector<mint> &s) { // const int N = (int)s.size(); // vector<mint> b, c; // b.reserve(N + 1); // c.reserve(N + 1); // b.push_back(mint(1)); // c.push_back(mint(1)); // mint y = mint(1); // for(int ed = 1; ed <= N; ed++){ // int l = int(c.size()), m = int(b.size()); // mint x = 0; // for (int i = 0; i < l; i++) x += c[i] * s[ed - l + i]; // b.emplace_back(mint(0)); // m++; // if(x == mint(0)) continue; // mint freq = x / y; // if(l < m){ // auto tmp = c; // c.insert(begin(c), m - l, mint(0)); // for (int i = 0; i < m; i++) c[m - 1 - i] -= freq * b[m - 1 - i]; // b = tmp; // y = x; // }else{ // for (int i = 0; i < m; i++) c[l - 1 - i] -= freq * b[m - 1 - i]; // } // } // reverse(begin(c), end(c)); // return c; // } // // BostanMori // // input: P(x)/Q(x),deg(P(x))<deg(Q(x)), // // output: [x^N](P(x)/Q(x)) // // O(dlog(d)logN), (d := deg(Q(x))) // // TODO: MSB-firstにするともっと早いらしい // // verified: https://judge.yosupo.jp/submission/199853 // mint BostanMori(vector<mint> P,vector<mint> Q,ll N){ // while(N){ // vector<mint> _Q(Q.size()); // for(int i=0;i<Q.size();i++) _Q[i] = i&1 ? -Q[i] : Q[i]; // vector<mint> nP = convolution(P,_Q); // vector<mint> nQ = convolution(Q,_Q); // Q.resize(nQ.size()/2 + 1); // for(int i=0;i<nQ.size();i+=2) Q[i/2] = nQ[i]; // if(N&1){ // P.resize(nP.size()/2); // for(int i=1;i<nP.size();i+=2) P[i/2] = nP[i]; // }else{ // P.resize((nP.size() + 1)/2); // for(int i=0;i<nP.size();i+=2) P[i/2] = nP[i]; // } // N /= 2; // } // return P[0]/Q[0]; // } // mint pw(mint a,ll x){ // mint ret = 1; // while(x){ // if(x&1) (ret *= a); // (a *= a); x /= 2; // } // return ret; // } // // f^k mod x^N をsparceなfに対して計算 // // [x^0]f \neq 0 を仮定 // // fの非零項がm個で、O(mN) になる // // verified: https://atcoder.jp/contests/nadafes2022_day1/submissions/52160796 // vector<mint> sparse_pow(vector<mint> &f,int k,int N){ // assert(f.size()); // assert(f[0]!=0); // mint iv = pw(f[0],mod - 2); // vector<pair<int,mint>> ff; // for(int i=1;i<f.size();i++){ // if(f[i].val()) ff.push_back({i,f[i]}); // } // vector<mint> ret(N); // ret[0] = pw(f[0],k); // for(int i=1;i<N;i++){ // for(int j=0;j<ff.size();j++){ // int deg = ff[j].first; // if(deg>i) break; // ret[i] += ff[j].second*deg*ret[i - deg]; // } // ret[i] *= k; // for(int j=0;j<ff.size();j++){ // int deg = ff[j].first; // if(deg>i) break; // ret[i] -= ff[j].second*(i - deg)*ret[i - deg]; // } // ret[i] *= inv[i]; // } // return ret; // } int main(){ int p1,p2,q1,q2,t; cin >> p1 >> p2 >> q1 >> q2 >> t; mint p = (mint)p1/(mint)p2; mint q = (mint)q1/(mint)q2; vector<mint> g(t + 2),h(t + 1); mint pr = 1,a = q; for(int i=0;i<=t;i++){ g[i + 1] = -pr; h[i] = pr; pr *= a; a *= q; } g[0] = 1; for(int i=1;i<=t;i++) g[i] *= p; vector<mint> f = convolution(fps_inv(g),h); cout << f[t].val() << "\n"; // for(int i=0;i<=2;i++) cout << (g[i]*8).val() << " "; // cout << "\n"; // for(int i=0;i<=2;i++) cout << (h[i]*64).val() << " "; // cout << "\n"; }