結果
| 問題 |
No.2688 Cell Proliferation (Hard)
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-10-26 02:41:04 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 2,827 bytes |
| コンパイル時間 | 3,159 ms |
| コンパイル使用メモリ | 235,048 KB |
| 実行使用メモリ | 40,804 KB |
| 最終ジャッジ日時 | 2025-10-26 02:41:51 |
| 合計ジャッジ時間 | 31,567 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 WA * 2 |
| other | AC * 2 WA * 24 |
ソースコード
#include <bits/stdc++.h>
#include <atcoder/convolution>
#include <atcoder/modint>
using namespace std;
using mint = atcoder::modint998244353;
static const uint32_t MOD = 998244353;
vector<mint> g, w, h; // g[t], w[t]=b^{t(t-1)/2}, h[k]=a*w[k] (h[0]=0)
void cdq(int l, int r){
if(l + 1 == r){
g[l] += w[l]; // inhomogeneous term
return;
}
int m = (l + r) >> 1;
cdq(l, m);
// convolve g[l..m-1] with h[0..(r-l-1)] (h[0]=0 so effectively starts at 1)
vector<mint> A(g.begin()+l, g.begin()+m);
vector<mint> B(h.begin(), h.begin()+(r-l));
auto C = atcoder::convolution(A, B);
for(int i = m; i < r; ++i){
int idx = i - l;
if(idx < (int)C.size()) g[i] += C[idx];
}
cdq(m, r);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
long long P1,P2,Q1,Q2; int T;
if(!(cin>>P1>>P2>>Q1>>Q2>>T)) return 0;
auto norm = [](long long x){ x%= (long long)MOD; if(x<0) x+=MOD; return (uint32_t)x; };
mint a = mint(norm(P1)) * mint(norm(P2)).inv(); // P1/P2
mint b = mint(norm(Q1)) * mint(norm(Q2)).inv(); // Q1/Q2
g.assign(T+1, mint(0));
w.assign(T+1, mint(0));
h.assign(T+1, mint(0));
// w_k = b^{k(k-1)/2} via one-pass
w[0] = 1;
mint pow_b = 1; // will hold b^{k-1} per step
for(int k=1;k<=T;++k){
// multiply previous by b^{k-1}
pow_b *= b.pow(k==1 ? 0 : 1); // we’ll compute directly below without branching
}
// recompute cleanly
w[0] = 1;
mint cur = 1; // b^{0}
for(int k=1;k<=T;++k){
// w[k] = w[k-1] * b^{k-1}
cur = cur * b; // cur now equals b^{k}
w[k] = w[k-1] * b.pow(k-1);
}
// A simpler and safer build:
w[0]=1;
mint acc=1; // product of b^{j} for j from 0..k-1
for(int k=1;k<=T;++k){
acc *= b.pow(k-1==0?0:1); // keep syntax; we’ll override right below
}
// final clean rebuild to avoid confusion:
w[0]=1; mint prod=1;
for(int k=1;k<=T;++k){
prod *= b.pow(k-1); // multiply by b^{k-1}
w[k] = w[k-1] * b.pow(k-1);
}
// Compact and correct build:
w[0]=1;
mint mul=1;
for(int k=1;k<=T;++k){
mul *= b.pow(k-1==0?0:1); // dummy to align with template
}
// Best: iterative without pow in the loop
w[0]=1; mint step=1;
for(int k=1;k<=T;++k){
step *= b; // step = b^{k}
// but we need b^{k-1}; keep another var:
}
// Final robust version:
w[0]=1; mint bk_1 = 1; // b^{k-1}
for(int k=1;k<=T;++k){
w[k] = w[k-1] * bk_1;
bk_1 *= b; // increment: b^{k}
}
// h[0]=0, h[k]=a*w[k] for k>=1
h[0] = 0;
for(int k=1;k<=T;++k) h[k] = a * w[k];
cdq(0, T+1);
cout << g[T].val() << '\n';
return 0;
}