其他分享
首页 > 其他分享> > 【题解】Luogu P5405 [CTS2019]氪金手游

【题解】Luogu P5405 [CTS2019]氪金手游

作者:互联网

原题传送门

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

\[1 \rightarrow 2 \rightarrow 3 \rightarrow …… \rightarrow n\]

\[P(1\rightarrow n)=\prod_{i=1}^n(\frac{w_i}{Sum}\sum_{i=0}^{\inf}(\frac{Sum-Sw_i}{Sum})^i)=\prod_{i=1}^n\frac{w_i}{Sw_i}\]

考虑有反向边

\[1 \rightarrow 2 \rightarrow …… k \leftarrow k+1 \rightarrow …… \rightarrow n\]

\[P=P(1 \rightarrow k) \times P(k+1 \rightarrow n)-P(1 \rightarrow 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;
}

标签:p2,ch,题解,p1,金手游,define,buf,P5405,rightarrow
来源: https://www.cnblogs.com/yzhang-rp-inf/p/10925807.html