結果
問題 | No.2688 Cell Proliferation (Hard) |
ユーザー |
![]() |
提出日時 | 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; }