結果

問題 No.1857 Gacha Addiction
ユーザー ytqm3ytqm3
提出日時 2022-02-25 22:06:22
言語 C++17
(gcc 13.2.0 + boost 1.83.0)
結果
AC  
実行時間 1,102 ms / 6,000 ms
コード長 8,288 bytes
コンパイル時間 2,505 ms
コンパイル使用メモリ 218,864 KB
実行使用メモリ 173,284 KB
最終ジャッジ日時 2023-09-16 17:04:34
合計ジャッジ時間 37,916 ms
ジャッジサーバーID
(参考情報)
judge12 / judge13
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 44 ms
50,148 KB
testcase_01 AC 44 ms
49,920 KB
testcase_02 AC 44 ms
49,892 KB
testcase_03 AC 44 ms
49,876 KB
testcase_04 AC 59 ms
52,088 KB
testcase_05 AC 58 ms
51,888 KB
testcase_06 AC 59 ms
52,024 KB
testcase_07 AC 59 ms
51,892 KB
testcase_08 AC 58 ms
52,092 KB
testcase_09 AC 366 ms
84,740 KB
testcase_10 AC 347 ms
84,768 KB
testcase_11 AC 343 ms
84,988 KB
testcase_12 AC 343 ms
84,684 KB
testcase_13 AC 343 ms
84,636 KB
testcase_14 AC 1,100 ms
172,900 KB
testcase_15 AC 1,096 ms
172,928 KB
testcase_16 AC 1,095 ms
173,284 KB
testcase_17 AC 1,095 ms
173,064 KB
testcase_18 AC 1,095 ms
172,792 KB
testcase_19 AC 1,098 ms
173,092 KB
testcase_20 AC 1,097 ms
173,040 KB
testcase_21 AC 1,095 ms
173,040 KB
testcase_22 AC 1,098 ms
172,932 KB
testcase_23 AC 1,099 ms
172,932 KB
testcase_24 AC 1,096 ms
173,116 KB
testcase_25 AC 1,100 ms
172,896 KB
testcase_26 AC 1,094 ms
172,984 KB
testcase_27 AC 1,095 ms
172,964 KB
testcase_28 AC 1,096 ms
173,244 KB
testcase_29 AC 1,094 ms
172,904 KB
testcase_30 AC 1,100 ms
173,128 KB
testcase_31 AC 1,098 ms
173,060 KB
testcase_32 AC 1,102 ms
172,896 KB
testcase_33 AC 1,096 ms
172,956 KB
testcase_34 AC 1,093 ms
172,948 KB
testcase_35 AC 1,093 ms
172,928 KB
testcase_36 AC 1,100 ms
172,952 KB
testcase_37 AC 1,099 ms
173,104 KB
testcase_38 AC 1,096 ms
173,044 KB
testcase_39 AC 369 ms
87,624 KB
testcase_40 AC 383 ms
88,996 KB
testcase_41 AC 526 ms
109,548 KB
testcase_42 AC 147 ms
63,800 KB
testcase_43 AC 1,003 ms
166,920 KB
testcase_44 AC 1,085 ms
172,948 KB
testcase_45 AC 44 ms
50,056 KB
testcase_46 AC 44 ms
49,900 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include<bits/stdc++.h>
typedef uint64_t u64;
typedef int64_t i64;
using namespace std;

template<u64 mod> struct modint{
  u64 val;
  modint(i64 val_=0):val((val_%i64(mod)+i64(mod))%i64(mod)){}
  modint operator-(){
    return (val==0)?0:mod-val;
  }
  modint operator+(modint rhs){
    return modint(*this)+=rhs;
  }
  modint operator-(modint rhs){
    return modint(*this)-=rhs;
  }
  modint operator*(modint rhs){
    return modint(*this)*=rhs;
  }
  modint operator/(modint rhs){
    return modint(*this)/=rhs;
  }
  modint operator^(i64 rhs){
    return modint(*this)^=rhs;
  }
  modint &operator+=(modint rhs){
    val+=rhs.val,val-=((val>=mod)?mod:0);
    return (*this);
  }
  modint &operator-=(modint rhs){
    val+=((val<rhs.val)?mod:0),val-=rhs.val;
    return (*this);
  }
  modint &operator*=(modint rhs){
    val=val*rhs.val%mod;
    return (*this);
  }
  modint &operator/=(modint rhs){
    return (*this)*=rhs^(mod-2);
  }
  modint &operator^=(i64 rhs){
    modint res=1,now=(*this);
    while(rhs){
      res*=((rhs&1)?now:1),now*=now,rhs>>=1;
    }
    return (*this)=res;
  }
  bool operator==(modint rhs){
    return val==rhs.val;
  }
  bool operator!=(modint rhs){
    return val!=rhs.val;
  }
  friend std::ostream &operator<<(std::ostream& os,modint x){
    return os<<(x.val);
  }
  friend std::istream &operator>>(std::istream& is,modint& x){
    u64 t;
    is>>t,x=t;
    return is;
  }
};

template<u64 mod> struct NTT{
  typedef modint<mod> mint;
  mint g;
  vector<int> rev;
  NTT(){
    for(g=2;;g+=1){
      if((g^((mod-1)>>1))!=1){
        return;
      }
    }
  }
  void dft(vector<mint>& f){
    int siz=f.size();
    for(int i=0;i<siz;++i){
      if(i<rev[i]){
        swap(f[i],f[rev[i]]);
      }
    }
    for(int b=1;b<siz;b<<=1){
      mint zeta=g^((mod-1)/(2*b));
      for(int i=0;i<siz;i+=2*b){
        mint now=1;
        for(int j=0;j<b;++j){
          mint s=f[i+j],t=f[i+j+b]*now;
          f[i+j]=s+t,f[i+j+b]=s-t;
          now*=zeta;
        }
      }
    }
  }
  vector<mint> operator()(vector<mint> a,vector<mint> b){
    int cnt=0,siz=1,mxsiz=a.size()+b.size()-1;
    while(siz<mxsiz){
      siz<<=1,++cnt;
    }
    rev.resize(siz);
    for(uint32_t i=0;i<siz;++i){
      rev[i]=(rev[i>>1]>>1)+(1<<cnt-1)*(i&1);
    }
    a.resize(siz),b.resize(siz),dft(a),dft(b);
    for(int i=0;i<siz;++i){
      a[i]*=b[i];
    }
    dft(a),reverse(a.begin()+1,a.end()),a.resize(mxsiz);
    mint isiz=mint(1)/siz;
    for(int i=0;i<siz;++i){
      a[i]*=isiz;
    }
    return a;
  }
};

template<u64 mod> struct FPS{
  typedef modint<mod> mint;
  NTT<mod> ntt;
  vector<mint> val;
  FPS():val({0}){}
  FPS(mint t):val({t}){}
  FPS(int siz):val(max(1,siz)){}
  FPS(initializer_list<mint> init):val(init){}
  FPS(vector<mint> init):val(init){}
  mint &operator[](int i){
    return val[i];
  }
  int size(){
    return val.size();
  }
  void resize(int siz){
    val.resize(siz);
  }
  FPS& resize_(int siz){
    auto tmp=val;
    tmp.resize(siz);
    return (*this)=tmp;
  }
  FPS operator-(){
    for(mint& v:val){
      v=mint(0)-v;
    }
    return (*this);
  }
  FPS& operator+=(mint rhs){
    val[0]+=rhs;
    return (*this);
  }
  FPS& operator-=(mint rhs){
    val[0]-=rhs;
    return (*this);
  }
  FPS& operator*=(mint rhs){
    for(auto& v:val){
      v*=rhs;
    }
    return (*this);
  }
  FPS& operator/=(mint rhs){
    for(auto& v:val){
      v/=rhs;
    }
    return (*this);
  }
  FPS operator+(mint rhs){
    return FPS(*this)+=rhs;
  }
  FPS operator-(mint rhs){
    return FPS(*this)-=rhs;
  }
  FPS operator*(mint rhs){
    return FPS(*this)*=rhs;
  }
  FPS operator/(mint rhs){
    return FPS(*this)/=rhs;
  }
  FPS& operator+=(FPS rhs){
    resize(max(this->size(),rhs.size()));
    for(int i=0;i<int(rhs.size());++i){
      (*this)[i]+=rhs[i];
    }
    return (*this);
  }
  FPS& operator-=(FPS rhs){
    resize(max(this->size(),rhs.size()));
    for(int i=0;i<int(rhs.size());++i){
      (*this)[i]-=rhs[i];
    }
    return (*this);
  }
  FPS& operator*=(FPS rhs){
    val=ntt(val,rhs.val);
    return (*this);
  }
  FPS& operator/=(FPS rhs){
    return (*this)*=rhs.inv();
  }
  FPS& operator>>=(int k){
    if(int(val.size())<=k){
      return (*this)={0};
    }
    FPS res=val;
    res.val.erase(res.val.begin(),res.val.begin()+k);
    return (*this)=res;
  }
  FPS& operator<<=(int k){
    FPS res=val;
    res.val.insert(res.val.begin(),k,mint(0));
    return (*this)=res;
  }
  FPS operator+(FPS rhs){
    return FPS(*this)+=rhs;
  }
  FPS operator-(FPS rhs){
    return FPS(*this)-=rhs;
  }
  FPS operator*(FPS rhs){
    return FPS(*this)*=rhs;
  }
  FPS operator/(FPS rhs){
    return FPS(*this)/=rhs;
  }
  FPS operator<<(int k){
    return FPS(*this)<<=k;
  }
  FPS operator>>(int k){
    return FPS(*this)>>=k;
  }
  FPS shrink(){
    for(int i=val.size()-1;i>0;--i){
      if(val[i]==0){
        val.pop_back();
      }
      else{
        break;
      }
    }
    return (*this);
  }
  FPS diff_(){
    if(val.size()==1){
      return (*this)={0};
    }
    FPS f(val.size()-1);
    for(size_t i=1;i<val.size();++i){
      f[i-1]=val[i]*i;
    }
    return f;
  }
  FPS integral_(){
    FPS f(val.size()+1);
    for(size_t i=0;i<val.size();++i){
      f[i+1]=val[i]/(i+1);
    }
    return f;
  }
  FPS inv_(int mx=-1){
    if(mx==-1){
      mx=val.size();
    }
    if(val[0]==0){
      assert(0);
    }
    FPS g({mint(1)/val[0]});
    int now=1;
    while(now<mx){
      now<<=1;
      FPS t=(*this);
      t.resize(now);
      t*=g;
      t=-t+mint(2);
      g*=t;
      g.resize(now);
    }
    g.resize(mx);
    return g;
  }
  FPS exp_(int mx=-1){
    if(mx==-1){
      mx=val.size();
    }
    if(val[0]!=0){
      assert(0);
    }
    FPS g(mint(1));
    int now=1;
    while(now<mx){
      now<<=1;
      FPS t=(*this);
      t.resize(now);
      g*=t-g.log_(now)+mint(1);
      g.resize(now);
    }
    g.resize(mx);
    return g;
  }
  FPS log_(int mx=-1){
    if(mx==-1){
      mx=val.size();
    }
    if(val[0]!=1){
      assert(0);
    }
    auto f=(*this);
    f.resize(mx);
    return (f.diff_()/f).integral_().resize_(mx);
  }
  FPS pow_(i64 k,int mx=-1){
    if(mx==-1){
      mx=val.size();
    }
    i64 t=0;
    for(auto v:val){
      if(v==0){
        t++;
      }
      else{
        break;
      }
    }
    auto f=(*this)>>t;
    if(f[0]==0){
      f={0},f.resize(mx);
      return f;
    }
    mint c=f[0];
    f/=c;
    (f.log(mx)*=mint(k)).exp(mx)*=(c^k);
    if(t*k<=mx){
      f<<=t*k;
      f.resize(mx);
      return f;
    }
    else{
      f={0},f.resize(mx);
      return f;
    }
  }
  FPS& diff(){
    return (*this)=diff_();
  }
  FPS& integral(){
    return (*this)=integral_();
  }
  FPS& inv(int mx=-1){
    return (*this)=inv_(mx);
  }
  FPS& exp(int mx=-1){
    return (*this)=exp_(mx);
  }
  FPS& log(int mx=-1){
    return (*this)=log_(mx);
  }
  FPS& pow(i64 k,int mx=-1){
    return (*this)=pow_(k,mx);
  }
};

template<u64 mod> FPS<mod> product(vector<FPS<mod>> a){
  int siz=1;
  while(siz<int(a.size())){
    siz<<=1;
  }
  vector<FPS<mod>> res(siz*2-1,{1});
  for(int i=0;i<int(a.size());++i){
    res[i+siz-1]=a[i];
  }
  for(int i=siz-2;i>=0;--i){
    res[i]=res[2*i+1]*res[2*i+2];
  }
  return res[0];
}

template<u64 mod> vector<modint<mod>> stirling_number2(int N){
  typedef modint<mod> mint;
  FPS<mod> f(N+1),g(N+1);
  mint fact=1;
  for(int i=0;i<=N;++i){
    f[i]=(mint(i)^N)/fact;
    g[i]=(mint(-1)^i)/fact;
    fact*=i+1;
  }
  f*=g;
  vector<mint> res(N+1);
  for(int i=0;i<=N;++i){
    res[i]=f[i];
  }
  return res;
}

template<typename T> struct comb{
  vector<T> dat,idat;
  comb(int mx=3000000):dat(mx+1,1),idat(mx+1,1){
    for(int i=1;i<=mx;++i){
      dat[i]=dat[i-1]*i;
    }
    idat[mx]/=dat[mx];
    for(int i=mx;i>0;--i){
      idat[i-1]=idat[i]*i;
    }
  }
  T operator()(int n,int k){
    if(n<0||k<0||n<k){
      return 0;
    }
    return dat[n]*idat[k]*idat[n-k];
  }
};

int main(){
  typedef modint<998244353> mint;
  constexpr u64 mod=998244353;
  int N,S;
  cin>>N>>S;
  vector<FPS<mod>> f(N);
  comb<mint> C;
  mint invS=mint(1)/S;
  for(int i=0;i<N;++i){
    mint p;
    cin>>p;
    f[i]={1,p*invS};
  }
  auto g=product(f);
  mint ans=0;
  for(int i=0;i<=N;++i){
    ans+=C.dat[i]*g[i];
  }
  cout<<ans<<endl;
}
0