zoukankan      html  css  js  c++  java
  • 【题解】Luogu P5405 [CTS2019]氪金手游

    原题传送门

    我们珂以先考虑一条链的情况,设(sum)为所有(w_i)的总和,(Sw_i)表示(sum_{j=i}^nw_i)

    $$1 ightarrow 2 ightarrow 3 ightarrow …… ightarrow n$$

    $$P(1 ightarrow n)=prod_{i=1}^n(frac{w_i}{Sum}sum_{j=0}^{inf}(frac{Sum-Sw_i}{Sum})^j)=prod_{i=1}^nfrac{w_i}{Sw_i}$$

    考虑有反向边

    $$1 ightarrow 2 ightarrow …… k leftarrow k+1 ightarrow …… ightarrow n$$

    由容斥原理可得:

    $$P=P(1 ightarrow k) imes P(k+1 ightarrow n)-P(1 ightarrow n)$$

    我们珂以由链推广到树

    (f[i][j])表示(i)的子树权值和为(j)时状态合法的概率

    暴力dp即可

    #include <bits/stdc++.h>
    #define ll long long
    #define N 1005
    #define mod 998244353
    #define getchar nc
    using namespace std;
    inline char nc(){
        static char buf[100000],*p1=buf,*p2=buf;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    inline int read()
    {
        register int x=0,f=1;register char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
        return x*f;
    }
    inline void write(register int x)
    {
        if(!x)putchar('0');if(x<0)x=-x,putchar('-');
        static int sta[20];register int tot=0;
        while(x)sta[tot++]=x%10,x/=10;
        while(tot)putchar(sta[--tot]+48);
    }
    inline ll fastpow(register ll a,register int b)
    {
    	ll res=1;
    	while(b)
    	{
    		if(b&1)
    			res=(res*a)%mod;
    		b>>=1;
    		a=(a*a)%mod;
    	}
    	return res;
    }
    struct edge{
    	int to,next,st;
    }e[N<<1];
    int head[N],cnt;
    inline void add(register int u,register int v,register int w)
    {
    	e[++cnt]=(edge){v,head[u],w};
    	head[u]=cnt;
    }
    int n,p[N][4],inv[N*3],f[N][N*3],g[N*3],size[N],ans;
    inline void dfs(register int x,register int fa)
    {
    	f[x][0]=1;
    	for(register int i=head[x];i;i=e[i].next)
    	{
    		int v=e[i].to;
    		if(v==fa)
    			continue;
    		dfs(v,x);
    		memset(g,0,sizeof(g));
    		for(register int j=0;j<=size[x];++j)
    			for(register int k=0;k<=size[v];++k)
    			{
    				g[j+k]=(g[j+k]+1ll*f[x][j]*f[v][k]%mod*e[i].st%mod)%mod;
    				if(e[i].st!=1)
    					g[j]=(g[j]+1ll*f[x][j]*f[v][k]%mod)%mod;
    			}
    		memcpy(f[x],g,sizeof(g));
    		size[x]+=size[v];
    	}
    	memset(g,0,sizeof(g));
    	for(register int j=0;j<=size[x];++j)
    		for(register int k=1;k<=3;++k)
    			g[j+k]=(g[j+k]+1ll*f[x][j]*k%mod*inv[j+k]%mod*p[x][k]%mod)%mod;
    	memcpy(f[x],g,sizeof(g));
    	size[x]+=3;
    }
    int main()
    {
    	n=read();
    	for(register int i=1;i<=n;++i)
    	{
    		int x=0;
    		for(register int j=1;j<=3;++j)
    		{
    			p[i][j]=read();
    			x+=p[i][j];
    		}
    		for(register int j=1;j<=3;++j)
    			p[i][j]=p[i][j]*fastpow(x,mod-2)%mod;
    	}
    	for(register int i=1;i<n;++i)
    	{
    		int u=read(),v=read();
    		add(u,v,1);
    		add(v,u,mod-1);
    	}
    	inv[1]=1;
    	for(register int i=2;i<=n*3;++i)
    		inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    	dfs(1,0);
    	for(register int i=1;i<=n*3;++i)
    		ans=(ans+f[1][i])%mod;
    	write(ans);
    	return 0;
    }
    
    
  • 相关阅读:
    Oracle EBS OM 主要API示例
    WIP 投料报 Invalid Serial Number
    物料事务处理interface与temp解析
    INV_TXN_MANAGER_PUB.PROCESS_TRANSACTIONS
    FND Debug Log(FND_LOG_MESSAGES)
    Oracle Apps DBA 常用命令
    详解EBS接口开发之WIP模块接口
    使用Java管理千台规模Linux服务器_入门
    windows下spark开发环境配置
    零成本实现Android/iOS自动化测试:基于Appium和Test Perfect
  • 原文地址:https://www.cnblogs.com/yzhang-rp-inf/p/10925807.html
Copyright © 2011-2022 走看看