观察可以发现,对于当前节点 i ,从该节点所有子树中选出一些点后构成的节点集合的 LCA 一定是是节点 i 。
这样子可以分成两种情况考虑:
选择节点 i
不选节点 i
不能单独只选一棵子树上的节点 (否则 LCA 就不是 i 了)
所有选择不能是空集 (题目规定)
对于这种情况直接算比较难算我们可以反着算(正难则反)
当前的方案数可以表示为: 所有子树随便选的方案 - 只选一颗子树的方案(不为空) + 所有子树都不选的方案数(方案数为1)
 每次 DFS 时可以返回当前子树的节点数量。
 时间复杂度为 O(nlogn)
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 1e9 + 7;
int qmi(int a, int b){
    int res = 1 % mod;
    while(b)
    {
        if(b & 1) res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}
signed main (){
    ios::sync_with_stdio(false);
    std::cin.tie(0);
    int n; cin >> n;
    vector<vector<int>> g(n + 1);
    for(int i = 0; i < n - 1; i ++)
    {
        int a, b; cin >> a >> b;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    vector<int> f(n + 1);
    auto dfs = [&](auto dfs, int u, int pre) -> int{
        vector<int> t{1};
        int cnt = 1;
        for(auto i : g[u])
            if(i != pre)
            {
                int ans = dfs(dfs, i, u);
                t.push_back(ans);
                cnt += ans;
            }
        int m = t.size();
        int add = 1, mul = 1;
        for(int i = 1; i < m; i ++)  // 第二种情况不选当前节点
        {
            int kk = qmi(2, t[i]);
            mul = mul * kk % mod;
            add += kk - 1;
            add = (add + mod) % mod;
        }
      	// 选了当前节点的方案数其实就是 mul
        int res = (mul * 2 - add+ mod) % mod;
        res %= mod;
        f[u] = res;
        return cnt;
    };
    dfs(dfs, 1, -1);
    for(int i = 1; i <= n; i ++)
        cout << f[i] << " \n"[i == n];
    return 0;
}
# 差分数组
n, m = list(map(int, input().split()))
lefts = list(map(int, input().split()))
rights = list(map(int, input().split()))
Q = int(input())
nums = list(map(int, input().split()))
d = [0] * (n + 2)
for i in range(m):
    left = lefts[i]
    right = rights[i]
    d[left] += 1
    d[right + 1] -= 1
presum = [0]
for x in d:
    presum.append(presum[-1] + x)
for q in nums:
    print(presum[q + 1], end = " ")
        最近公共祖先简称LCA(Lowest Common Ancestor)两个节点的最近公共祖先,就是这两个点的公共祖先里面离根最远的那个。 小红有一棵有根树,树的根节点为1号节点。定义f(i)是:LCA为i的非空节点集个数,小红想知道f(1)到f(n)的值。由于f(i)可能很大,因此你需要输出f(i)对109+7取模后的结果
第一行输入一个正整数n,代表树的节点个数
接下来n−1行,每行两个整数u,v(1≤u,v≤n)表示树上的边。
1≤n≤105
输出n个整数表示答案
输入
3
1 2
2 3
输出
4 2 1
说明
LCA为1的节点集:(1),(1,2),(1,3),(1,2,3)
LCA为2的节点对:(2),(2,3)
LCA为3的节点对:(3)
输入
5
1 2
1 3
2 4
2 5
输出
23 5 1 1 1