[CTS2019]氪金手游

Solution

先考虑外向树的情况,这样根一定是最小的,所有子节点都必须比它后访问,而所有非子节点多久抽到无所谓。假定每个点的 \(w_i\) 是定值,\(s_i\)\(i\) 的子树和,\(S\) 是总和,那么概率就是

\[\prod_{i=1}^n \frac{w_i}{S} \sum_{j=0}^{\infty} (\frac{S-s_i}{S})^{j}=\prod_{i=1}^n \frac{w_i}{s_i} \]

发先最后答案只和每个点的 \(w\)\(s\) 有关。考虑把 \(w\)\(s\) 压入状态进行 dp,然后发现 \(w\) 可以去掉。记 \(dp[u][x]\) 表示考虑 \(u\) 这个子树, \(w_i\) 和为 \(x\) 且符合关系的概率。这样就得到一个 \(O(n^2)\) 的 dp。

再考虑加入反向边,一个容斥小技巧,将反向边拆成不考虑这条边(分成两个连通块),减去这条边是正向边的情况。后者就是外向树的情况,前者将其分成两个连通块,容易发现这两个连通块互不干扰,所以概率就是两个分别 dp 后的乘积,也即一个外向树森林。那么最后的概率就可以通过枚举每条反向边的方向,然后 dp,再乘上一个容斥系数,求和。复杂度 \(O(2^n n^2)\)

又发现我们并不在意每条边具体是什么方向,容斥系数只和反向边没有反向的数量有关,而 dp 转移只和 \(w\)\(s\) 有关。所以考虑转移的时候如果是反向边就将概率乘上负一,由分配率知这样是对的。

#include<stdio.h>

const int N=1e3+7;
const int M=3e6+7;
const int Mod=998244353;

struct E{
    int next,to;
    bool tag;
}e[N<<1];

int head[N],cnt=0,n;
int inv[M],sz[N],dp[N][N*3],tmp[N*3];

inline void add(int id,int to){
    e[++cnt]=(E){head[id],to,0};
    head[id]=cnt;
    e[++cnt]=(E){head[to],id,1};
    head[to]=cnt;
}

void dfs(int u,int fa){
    sz[u]=1;
    for(int i=head[u];i;i=e[i].next){
        int v=e[i].to;
        if(fa==v) continue;
        dfs(v,u);
        for(int x=1;x<=sz[u]*3;x++)
            for(int y=1;y<=sz[v]*3;y++){
                int t=1ll*dp[u][x]*dp[v][y]%Mod;
                if(e[i].tag) tmp[x+y]=(tmp[x+y]-t+Mod)%Mod,tmp[x]=(tmp[x]+t)%Mod;
                else tmp[x+y]=(tmp[x+y]+t)%Mod;
            }
        sz[u]+=sz[v];
        for(int x=1;x<=sz[u]*3;x++) dp[u][x]=tmp[x],tmp[x]=0;
    }
    for(int i=1;i<=sz[u]*3;i++) dp[u][i]=1ll*dp[u][i]*inv[i]%Mod;
}

int main(){
    scanf("%d",&n); inv[1]=1;
    for(int i=2;i<M;i++)
        inv[i]=1ll*(Mod-Mod/i)*inv[Mod%i]%Mod;
    for(int i=1,a,b,c;i<=n;i++){
        scanf("%d%d%d",&a,&b,&c);
        int w=inv[a+b+c];
        dp[i][1]=1ll*a*w%Mod;
        dp[i][2]=1ll*b*w%Mod*2ll%Mod;
        dp[i][3]=1ll*c*w%Mod*3ll%Mod;
    }
    for(int i=1,u,v;i<n;i++)
        scanf("%d%d",&u,&v),add(u,v);
    dfs(1,0); int ans=0;
    for(int i=1;i<=3*n;i++) ans=(ans+dp[1][i])%Mod;
    printf("%d",ans);
}
posted @ 2021-06-23 21:53  Kreap  阅读(36)  评论(0编辑  收藏  举报