D:概率论
条件概率:求在某个条件发生的概率下,另一个条件发生的概率.
公式P(A|B) = P(AB)/P(A).
在这题中即可看成 恰好有k枚的概率/至少m枚的概率.
对于至少m枚的概率.
容斥求最多m-1枚反面的概率.
0枚反面时 C(n,0) * (1/2)^n
1枚反面时 C(n,1) * (1/2)^2
....
1减去这个和即为至少m枚反面的概率.

恰好k枚正面的概率C(n,k)*(1/2)^n.
Code:

LL f[N];
void init()
{
    f[0] = 1;for(int i=1;i<N;++i) f[i] = (f[i-1]*i)%Mod;
}
LL quick_mi(LL a,LL b)
{
    LL re = 1;
    while(b)
    {
        if(b&1) re = (re*a)%Mod;
        a = (a*a)%Mod;
        b >>= 1;
    }
    return re;
}
LL inv(LL n){return quick_mi(n,Mod-2)%Mod;}
LL C(LL n,LL m)
{
    return f[n]*inv(f[m])%Mod*inv(f[n-m])%Mod;
}
int main()
{
    init();
    int t;sd(t);
    while(t--)
    {
        int n,m,k;sddd(n,m,k);
        if(m+k > n) printf("0\n");
        else
        {
            LL ma1 = C(n,k)*inv(quick_mi(2,n))%Mod;
            LL tmp = 0;
            for(int i=0;i<m;++i)
            {
                tmp = (tmp+C(n,i)*inv(quick_mi(2,n))%Mod)%Mod;
            }
            tmp = (1-tmp+Mod)%Mod;
            LL ans = ma1*inv(tmp)%Mod;
            plr(ans);
        }
    }
    system("pause");
    return 0;
}

A:树形dp.(注意不包括路径上的点的权值)
dp[i]表示i点向下的最大价值。
对面每个点有两种情况
1.以这个点为中间媒介,这个点的两条子节点上的边相连为最大.
2.以这个点为起点,和向下的某条子节点边上的点相连为最大.

所以边更新dp值边进行比较,同时最后比较自己为起点,那么dp[i]显然就是i点往下的最大价值了,注意的是,这个dp[i]在最后更新完时显然已经将和子节点的边的权值计算在内。
然后dp[i]也可能是a[i],所以最后还要更新一下。

Code:

struct Node{int to,dis;};
LL a[N],dp[N],ans;
vector<Node> G[N];
void dfs(int u,int fa)
{
    for(auto t:G[u])
    {
        int v = t.to,d = t.dis;
        if(v == fa) continue;
        dfs(v,u);
        ans = max(ans,dp[u]+dp[v]+d);//以u为中间媒介,通过之前更新的最大dp[u]来更新dp[v].
        dp[u] = max(dp[u],dp[v]+d);//以v或者v以下的点为终点;显然dp[v]已经与a[v]比较过;
    }
    ans = max(ans,dp[u]+a[u]);//以u为起点
    dp[u] = max(dp[u],a[u]);
}
int main()
{
    int t;sd(t);
    while(t--)
    {
        ans = -INF;
        int n;sd(n);
        for(int i=1;i<=n;++i) G[i].clear(),dp[i] = -INF;
        for(int i=2;i<=n;++i)
        {
            int x,y;sdd(x,y);
            G[i].push_back(Node{x,y});
            G[x].push_back(Node{i,y});
        }
        for(int i=1;i<=n;++i) sld(a[i]);
        dfs(1,0);
        plr(ans);
    }
  //  system("pause");
    return 0;
}