• 【题解】[Codeforces 1067E] Random Forest Rank【结论题 概率DP】


    题目链接

    题意

    给定一棵树,每条边有 (dfrac{1}{2}) 的概率出现,求该森林邻接矩阵的轶的期望。(nleq 5 imes 10^5)

    题解

    结论:轶为最大匹配的两倍。

    秩相当于选一个最大的满秩的子矩阵。考虑子矩阵的行列式,一个有贡献的排列相当于找若干条有向边,使得每个点入度出度最大等于 1.
    这个东西相当于最大匹配。因为这是一棵树,这个东西是唯一的,行列式的值不会被抵消掉
    所以这个邻接矩阵的秩等于最大匹配。

    于是 DP 每个点与其儿子匹配的概率。

    #include<bits/stdc++.h>
    using namespace std;
    int getint(){
        int ans=0,f=1;
        char c=getchar();
        while(c<'0'||c>'9'){
            if(c=='-')f=-1;
            c=getchar();
        }
        while(c>='0'&&c<='9'){
            ans=ans*10+c-'0';
            c=getchar();
        }
        return ans*f;
    }
    const int N=5e5+10,mod=998244353,inv2=(mod+1)/2;
    struct bian{
        int e,n;
    };
    bian b[N<<1];
    int s[N],tot=0;
    void add(int x,int y){
        tot++;
        b[tot].e=y;
        b[tot].n=s[x];
        s[x]=tot;
    }
    
    int f[N];
    void ss(int x,int fa){
        f[x]=1;
        for(int i=s[x];i;i=b[i].n){
            int v=b[i].e;
            if(v==fa)continue;
            ss(v,x);
            f[x]=f[x]*(f[v]+1ll)%mod*inv2%mod;
        }
        f[x]=(mod+1-f[x])%mod;
    }
    
    int main(){
        int n=getint(),p2=1;
        for(int i=0;i<n-1;i++){
            int x=getint(),y=getint();
            add(x,y);
            add(y,x);
            p2<<=1;
            p2>=mod&&(p2-=mod);
        }
        ss(1,0);
        long long s=0;
        for(int i=1;i<=n;i++)s+=f[i];
        cout<<s%mod*2*p2%mod;
        return 0;
    }
    
    
  • 相关阅读:
    预编译命令 #if DEBUG
    conda常用命令
    tensorflow 安装指南
    LocNET和池化理解
    同时安装cuda8和cuda9
    np.transpose
    python中List的slice用法
    书单
    训练工程
    linux 查看进程
  • 原文地址:https://www.cnblogs.com/wallbreaker5th/p/14217970.html
Copyright © 2020-2023  润新知