• 「PKUWC2018」猎人杀


    https://loj.ac/problem/2541

    题解

    考虑容斥,令集合S为我们钦定S集合必须要在1号节点后面,那么答案为。

    [ans=sum_{S}(-1)^{|S|}P(S) ]

    然后这个(P(S))(frac{w_1}{w_1+w_S})

    这个需要想一想,或者我们考虑一个事情,就是每次死一个人概率的分母不会变,所以我们可以把它补成一样的,就是这个人死后有可能还会被选上,如果选上的话就再选一次,列出式子就是:

    [sum_{i=0}^{infty}(1-frac{w_s+w_1}{sum})frac{w_1}{sum} ]

    [frac{w_1}{w_1+w_s} ]

    所以我们要求所有的(w_s)

    我们令生成函数(G=sum_{i=0}^{infty}x^i)表示w的和为i的(sum)的系数和,因为总和题目有保证,所以就可以分治(FFT)了。

    代码

    #include<bits/stdc++.h>
    #define N 270002
    using namespace std;
    typedef long long ll;
    const int mod=998244353;
    const int G=3;
    const int Gi=332748118;
    ll a[42][N];
    int rev[N],w[N],cnt[N],n;
    int tot,rbs[N];
    inline ll rd(){
      ll x=0;char c=getchar();bool f=0;
      while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
      while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
      return f?-x:x;
    }
    inline void MOD(ll &x){x=x>=mod?x-mod:x;}
    inline ll power(ll x,ll y){
      ll ans=1;
      while(y){if(y&1)ans=ans*x%mod;x=x*x%mod;y>>=1;}
      return ans;
    }
    inline void NTT(ll *a,int l,int tag){
      for(int i=1;i<l;++i)if(i>rev[i])swap(a[i],a[rev[i]]);
      for(int i=1;i<l;i<<=1){
        ll wn=power(tag==1?G:Gi,(mod-1)/(i<<1));
        for(int j=0;j<l;j+=(i<<1)){
          ll w=1;
          for(int k=0;k<i;++k,w=w*wn%mod){
            ll x=a[j+k],y=a[i+j+k]*w%mod;
            MOD(a[j+k]=x+y);MOD(a[i+j+k]=x-y+mod);
          }
        }
      }
      if(tag<0){
        ll ny=power(l,mod-2);
        for(int i=0;i<l;++i)a[i]=a[i]*ny%mod;
      }
    }
    void solve(int now,int L,int R){
      if(L==R){
         cnt[now]=w[L];
         a[now][0]=1;a[now][w[L]]=mod-1;
         return;
      }
      int mid=(L+R)>>1;
      int x=rbs[0]?rbs[rbs[0]--]:++tot,y=rbs[0]?rbs[rbs[0]--]:++tot;
      solve(x,L,mid);solve(y,mid+1,R);
      cnt[now]=cnt[x]+cnt[y];
      int l=1,num=0;
      while(l<=(cnt[now]))l<<=1,num++;
      for(int i=1;i<l;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<(num-1));
      NTT(a[x],l,1);NTT(a[y],l,1);
      for(int i=0;i<l;++i)a[now][i]=a[x][i]*a[y][i]%mod;
      NTT(a[now],l,-1);
      for(int i=0;i<l;++i)a[x][i]=0,a[y][i]=0;
      rbs[++rbs[0]]=x;rbs[++rbs[0]]=y;
    }
    int main(){
      n=rd();
      int sum=0;
      for(int i=1;i<=n;++i)w[i]=rd(),sum+=w[i];
      solve(0,2,n);
      ll ans=0;
      for(int i=0;i<=sum;++i){
        MOD(ans+=a[0][i]*power(w[1]+i,mod-2)%mod);
      }
      ans=ans*w[1]%mod;
      cout<<ans<<endl;
      return 0;
    }
    
  • 相关阅读:
    how to .bson file into mongodb
    celery 源生框架项目
    @property装饰器将getter方法变成了属性
    类继承实现--停车场可用车位
    vue 基于 webpack 中使用 ECharts
    windows10 docker 从C盘迁移到其他盘
    python 布隆过滤器的下载使用
    深入系统同步锁机制 GIL
    男神鹏:ubantu 18.0.4 安装go 1.10.4 和环境变量的配置以及卸载
    男神鹏:命令 'ls' 可在 '/bin/ls' 处找到
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/10941678.html
Copyright © 2020-2023  润新知