結果

問題 No.1875 Flip Cards
ユーザー ytqm3ytqm3
提出日時 2021-12-23 23:07:17
言語 C++17
(gcc 13.2.0 + boost 1.83.0)
結果
WA  
(最新)
AC  
(最初)
実行時間 -
コード長 6,348 bytes
コンパイル時間 5,132 ms
コンパイル使用メモリ 286,732 KB
実行使用メモリ 62,608 KB
最終ジャッジ日時 2023-09-22 12:56:48
合計ジャッジ時間 9,969 ms
ジャッジサーバーID
(参考情報)
judge12 / judge14
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 WA -
testcase_01 WA -
testcase_02 WA -
testcase_03 WA -
testcase_04 WA -
testcase_05 WA -
testcase_06 WA -
testcase_07 WA -
testcase_08 WA -
testcase_09 WA -
権限があれば一括ダウンロードができます

ソースコード

diff #

#include<bits/stdc++.h>
#include<atcoder/all>
typedef uint64_t u64;
typedef int64_t i64;
using namespace std;
template<u64 mod> using modint=atcoder::static_modint<mod>;

template<u64 mod> struct FPS{
  typedef modint<mod> mint;
  vector<mint> val;
  FPS():val({0}){}
  FPS(mint t):val({t}){}
  FPS(int siz):val(max(1,siz)){}
  FPS(initializer_list<modint<mod>> 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=atcoder::convolution(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 t(val[0]),g({mint(1)/val[0]});
    size_t now=1;
    while(now<mx){
      t.resize(now<<1);
      size_t ed=min(val.size(),now<<1);
      for(size_t i=now;i<ed;++i){
        t[i]=val[i];
      }
      now<<=1;
      g*=-(t*g)+mint(2);
      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 t(val[0]),g(mint(1));
    size_t now=1;
    while(now<mx){
      t.resize(now<<1);
      int ed=min(val.size(),now<<1);
      for(int i=now;i<ed;++i){
        t[i]=val[i];
      }
      now<<=1;
      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.pow(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> FPS<mod> inv_sum(int M,vector<FPS<mod>> f){
  int siz=1;
  while(siz<int(f.size())){
    siz<<=1;
  }
  vector<FPS<mod>> mol(siz*2-1),den(siz*2-1,{1});
  for(size_t i=0;i<f.size();++i){
    mol[i+siz-1]={1};
    den[i+siz-1]=f[i];
  }
  for(int i=siz-2;i>=0;--i){
    den[i]=den[2*i+1]*den[2*i+2];
    mol[i]=mol[2*i+1]*den[2*i+2]+mol[2*i+2]*den[2*i+1];
  }
  mol[0]*=den[0].inv(M+1);
  return mol[0].resize_(M+1);
}


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).pow(N)/fact;
    g[i]=mint(-1).pow(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;
}

int main(){
  constexpr u64 mod=998244353;
  typedef modint<mod> mint;
  int N,M;
  scanf("%d%d",&N,&M);
  mint prod=1;
  vector<FPS<mod>> f(N);
  for(int i=0;i<N;++i){
    int a,b,c;
    scanf("%d%d%d",&a,&b,&c);
    prod*=mint(a).pow(c);
    mint u=mint(a)/b,v=mint(1)/c;
    f[i]={u*v,v};
  }
  auto g=inv_sum(M,f);
  g.integral();
  g.exp();
  auto Sm=stirling_number2<mod>(M);
  mint ans=0,fact=1;
  for(int i=0;i<=M;++i){
    ans+=Sm[i]*fact*prod*g[i];
    fact*=i+1;
  }
  printf("%d\n",int(ans.val()));
}
0