結果
| 問題 |
No.2688 Cell Proliferation (Hard)
|
| コンテスト | |
| ユーザー |
nonon
|
| 提出日時 | 2024-03-20 22:43:49 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 1,778 ms / 4,000 ms |
| コード長 | 4,142 bytes |
| コンパイル時間 | 2,690 ms |
| コンパイル使用メモリ | 211,996 KB |
| 最終ジャッジ日時 | 2025-02-20 09:45:49 |
|
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 26 |
ソースコード
#include<bits/stdc++.h>
#include<atcoder/modint>
using namespace std;
using mint=atcoder::modint998244353;
template<typename mint>
struct Number_Theoretic_Transform
{
static vector<mint>dw,dw_inv;
static int log;
static mint root;
static void ntt(vector<mint>& f)
{
init();
const int n=f.size();
for(int m=n;m>>=1;)
{
mint w=1;
for(int s=0,k=0;s<n;s+=(m<<1))
{
for(int i=s,j=s+m;i<s+m;i++,j++)
{
mint x=f[i],y=f[j]*w;
f[i]=x+y,f[j]=x-y;
}
w*=dw[__builtin_ctz(++k)];
}
}
}
static void intt(vector<mint>& f, bool flag=true)
{
init();
const int n=f.size();
for(int m=1;m<n;m<<=1)
{
mint w=1;
for(int s=0,k=0;s<n;s+=(m<<1))
{
for(int i=s,j=s+m;i<s+m;i++,j++)
{
mint x=f[i],y=f[j];
f[i]=x+y,f[j]=(x-y)*w;
}
w*=dw_inv[__builtin_ctz(++k)];
}
}
if(flag)
{
mint cef=mint(n).inv();
for(int i=0;i<n;i++)f[i]*=cef;
}
}
private:
Number_Theoretic_Transform()=default;
static void init()
{
if(!dw.empty())return;
long long mod=998244353;
long long tmp=mod-1;
log=1;
while(tmp%2==0)
{
tmp>>=1;
log++;
}
dw.resize(log);
dw_inv.resize(log);
for(int i=0;i<log;i++)
{
dw[i]=-root.pow((mod-1)>>(i+2));
dw_inv[i]=dw[i].inv();
}
}
};
template<typename mint>
vector<mint>Number_Theoretic_Transform<mint>::dw=vector<mint>();
template<typename mint>
vector<mint>Number_Theoretic_Transform<mint>::dw_inv=vector<mint>();
template<typename mint>
int Number_Theoretic_Transform<mint>::log=0;
template<typename mint>
mint Number_Theoretic_Transform<mint>::root=mint(3);
template<typename mint>
struct relaxed_convolution
{
using NTT=Number_Theoretic_Transform<mint>;
relaxed_convolution(int n_):n(n_),i(0)
{
a.resize(n+1);
b.resize(n+1);
c.resize(n+1);
}
mint get(mint x, mint y)
{
assert(i<=n);
a[i]=x,b[i]=y;
c[i]+=a[i]*b[0]+(i?b[i]*a[0]:0);
i++;
if(i>n)return c[i-1];
for(int d=1,k=0;d<=i;d<<=1,k++)
{
if(i%(2*d)!=d)continue;
f.assign(2*d,0);
g.assign(2*d,0);
if(i==d)
{
for(int j=0;j<d;j++)f[j]=a[j];
for(int j=0;j<d;j++)g[j]=b[j];
NTT::ntt(f);
NTT::ntt(g);
for(int j=0;j<2*d;j++)f[j]*=g[j];
}
else
{
calc(k);
for(int j=0;j<d;j++)f[j]=a[i-d+j];
for(int j=0;j<d;j++)g[j]=b[i-d+j];
NTT::ntt(f);
NTT::ntt(g);
for(int j=0;j<2*d;j++)f[j]=f[j]*bs[k][j]+g[j]*as[k][j];
}
NTT::intt(f);
for(int j=i;j<min(i+d,n+1);j++)c[j]+=f[d+j-i];
}
return c[i-1];
}
private:
int n,i;
vector<mint>a,b,c,f,g;
vector<vector<mint>>as,bs;
void calc(int k)
{
if((int)as.size()<=k)
{
as.resize(k+1);
bs.resize(k+1);
}
if(!as[k].empty())return;
int d=1<<k;
vector<mint> s(a.begin(),a.begin()+2*d);
vector<mint> t(b.begin(),b.begin()+2*d);
NTT::ntt(s);
NTT::ntt(t);
as[k]=s,bs[k]=t;
}
};
long P1,P2,Q1,Q2,T;
mint dp[1<<20];
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin>>P1>>P2>>Q1>>Q2>>T;
mint P=mint(P1)/P2;
mint Q=mint(Q1)/Q2;
relaxed_convolution<mint> F(T+1);
dp[0]=1;
for(long i=1;i<=T;i++)
{
dp[i]=P*F.get(dp[i-1],Q.pow(i*(i-1)/2));
}
mint ans=0;
for(long i=0;i<=T;i++)ans+=dp[i]*Q.pow((T-i+1)*(T-i)/2);
cout<<ans.val()<<endl;
}
nonon