• The Preliminary Contest for ICPC Asia Xuzhou 2019 J Random Access Iterator (树形DP)


    每次循环向下寻找孩子时,随机选取一个孩子,设dp[u]为从u出发,不能得出正确答案的概率,则从u出发,走一次的情况下不能得出正确答案的概率是 P = (dp[v1]+dp[v2]+dp[v3]+……dp[vk]) / cnt_son[u] ,则从u出发,要走cnt_son[u]次,那么dp[u]=P^cnt_con[u]
    dp的意义也可以改成能得出正确答案的概率,下面的式子稍微改改就行了
    为了避免除法的精度问题,num/k %mod,它等于 num * ni %mod ,ni等于k在模mod意义下的逆元。

    #include <bits/stdc++.h>
    using namespace std;
    const int mod=1e9+7;
    const int maxn=1e6+10;
    
    long long N;
    vector<long long> vc[maxn];
    long long deep[maxn],dp[maxn],MaxDeep=-1,son[maxn];
    
    void dfs(long long u,long long pre)
    {
        deep[u]=deep[pre]+1;
        MaxDeep=max(MaxDeep,deep[u]);
        int size=vc[u].size();
        for (int i=0;i<size;i++) {
            if (vc[u][i]!=pre) {
                son[u]++;
                dfs(vc[u][i],u);
            }
        }
    }
    
    long long quick_pow(long long base,long long p)
    {
        long long ans=1;
        while (p) {
            if (p&1) {
                ans=ans*base%mod;
            }
            base=base*base%mod;
            p>>=1;
        }
        return ans;
    }
    
    void dfs2(long long u,long long pre)
    {
        if (!son[u]) {
            if (deep[u]==MaxDeep) {
                dp[u]=0;
            }
            else {
                dp[u]=1;
            }
            return ;
        }
        int size=vc[u].size();
        long long tmp=0,ni=quick_pow(son[u],mod-2);
        for (int i=0;i<size;i++) {
            if (vc[u][i]==pre) continue;
            dfs2(vc[u][i],u);
            tmp=(tmp+(dp[vc[u][i]]*ni)%mod)%mod;
        }
        dp[u]=quick_pow(tmp,son[u]);
    }
    
    int main()
    {
        scanf("%lld",&N);
        long long u,v;
        for (int i=1;i<N;i++) {
            scanf("%lld%lld",&u,&v);
            vc[u].push_back(v);
            vc[v].push_back(u);
        }
        dfs(1,0);
        dfs2(1,0);
        printf("%lld
    ",(1-dp[1]+mod)%mod);
        // for (int i=0;i<=N;i++) {
        //     printf("%lld %lld
    ",deep[i],son[i]);
        // }
        // printf("%lld
    ",MaxDeep);
        return 0;
    }
    
  • 相关阅读:
    Azure Application Gateway (6) 使用OpenSSL创建SAN证书
    MySQL常用函数整理,建议收藏!
    设计一个接口至少要考虑这14点!
    SpringBoot 常用读取配置文件的 3 种方法!
    MyBatisPlus常用功能总结!(附项目示例)
    接口测试神器Apifox,亲测好用!
    huey在windows下使用的坑
    sublimeCodeIntel在windows下安装的坑
    字符串生成二维码
    android中EditText有光标不弹出软键盘处理(转)
  • 原文地址:https://www.cnblogs.com/xyqxyq/p/12328862.html
Copyright © 2020-2023  润新知