• AGC038E Gachapon


    Link
    (SA=sumlimits_{i=1}^nA_a,SB=sumlimits_{i=1}^n(B_i-1))
    (S={t_1,cdots,t_n}),其中(t_i)表示(i)的个数达到(B_i)的时间,那么我们要求的就是(operatorname E(max(S)))
    考虑Min-Max容斥,(operatorname E(max(S))=sumlimits_{Tsubseteq S}(-1)^{|T|-1}operatorname E(min(T)))(min(T))就是(T)集合中第一次元素(i)的个数达到(B_i)的时间。
    根据期望的线性性,(operatorname E(min(T)))等于所有没有元素(i)的个数达到(B_i)的期望停留时间的和。
    (T)中的元素为(a_1,cdots,a_m)(a_i)出现过(x_i)次,记(S_T=sumlimits_{i=1}^mA_{a_i})
    我们知道到达该状态后期望留在该状态的时间是(sumlimits_{i=0}^{+infty}(frac{S_T}{SA})^i=frac{SA}{S_T}),因此我们只需要求出到达该状态的概率。
    根据可重组合的概率公式得到概率为((sumlimits_{i=1}^mx_i)!prodlimits_{i=1}^mfrac{(frac{A_{a_i}}{S_T})^{x_i}}{x_i!}=(sumlimits_{i=1}^mx_i)!S_T^{sumlimits_{i=1}^n x_i}prodlimits_{i=1}^mfrac{A_{a_i}^{x_i}}{x_i!})
    那么我们要求的的是所有下标集合(T)的所有(x_i)序列的期望停留时间的贡献之和,考虑dp。
    一个集合的贡献是((-1)^{m-1}(frac{SA}{S_T})(sumlimits_{i=1}^mx_i)!S_T^{sumlimits_{i=1}^n x_i}prodlimits_{i=1}^mfrac{A_{a_i}^{x_i}}{x_i!}),我们考虑把难以转移的(S_T)(sumlimits_{i=1}x_i)拿出来放进dp状态。
    (S_T=j)(sumlimits_{i=1}^mx_i=k),那么一个集合的贡献是((-1)^{m-1}(frac{SA}j)k!j^kprodlimits_{i=1}^mfrac{A_{a_i}^{x_i}}{x_i!})
    那么设(f_{i,j,k})只考虑前(i)个元素,所有(S_T=j)(sumlimits_{i=1}^mx_i=k)的集合的((-1)^{m-1}prodlimits_{i=1}^mfrac{A_{a_i}^{x_i}}{x_i!})之和。
    转移的话考虑多出来一个(i)元素会造成什么影响,显然我们只需要考虑包含(i)这个下标的集合,然后再枚举(i)的出现次数(lin[0,B_i)),就有(-1frac{A_i^l}{l!}f_{i-1,j,k} ightarrow f_{i,j+A_i,k+l})
    答案就是(sumlimits_{j=1}^ssumlimits_{k=0}^{SB}(frac{SA}{j})k!j^kf_{j,k})

    #include<cstdio>
    const int N=404,P=998244353;
    int f[N][N],A[N],B[N],fac[N],ifac[N];
    int read(){int x;scanf("%d",&x);return x;}
    int inc(int a,int b){return a+=b-P,a+(a>>31&P);}
    int dec(int a,int b){return a-=b,a+(a>>31&P);}
    int mul(int a,int b){return 1ll*a*b%P;}
    int pow(int a,int k){int r=1;for(;k;k>>=1,a=mul(a,a))if(k&1)r=mul(a,r);return r;}
    int main()
    {
        int n=read(),ans=0,s=0;
        f[0][0]=P-1,fac[0]=1;
        for(int i=1;i<=n;++i) s+=A[i]=read(),B[i]=read();
        for(int i=1;i<=400;++i) fac[i]=mul(fac[i-1],i);
        ifac[400]=pow(fac[400],P-2);
        for(int i=400;i;--i) ifac[i-1]=mul(ifac[i],i);
        for(int i=1;i<=n;++i)
    	for(int j=s;~j;--j)
    	    for(int k=400;~k;--k)
    		if(f[j][k])
    		    for(int l=0,r=1;l<B[i];++l,r=mul(r,A[i]))
    			f[j+A[i]][k+l]=dec(f[j+A[i]][k+l],mul(mul(r,ifac[l]),f[j][k]));
        for(int i=1;i<=s;++i)
            for(int r=pow(i,P-2),t=i==s? 1:mul(s,pow(i,P-2)),j=0,k=1;j<=400;++j,k=mul(k,r))
                ans=inc(ans,mul(mul(mul(f[i][j],fac[j]),k),t));
        printf("%d",ans);
    }
    
  • 相关阅读:
    设置cookie,读取cookie案例
    npm常用命令及版本号浅析
    nrm安装与使用
    ES6解构赋值
    nodemon 基本配置与使用
    nodejs开发辅助工具nodemon
    Node自动重启工具 nodemon
    深入浅出Object.defineProperty()
    js原生缓慢返回顶部函数封装
    The linux command 之权限
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12271362.html
Copyright © 2020-2023  润新知