LCA + 树上差分模板
https://www.luogu.com.cn/problem/P3258
点差分
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N = 3e5 + 10;
int a[N];
int head[N], nxt[N * 2], to[N * 2], E;
int w[N];
int c[N];
int f[N][20]; // 2 ^ 18
int dep[N];
void add(int x, int y)
{
to[E] = y;
nxt[E] = head[x];
head[x] = E++;
}
void dfs(int u, int fa)
{
for (int i = head[u]; i != -1; i = nxt[i])
{
int v = to[i];
if (v == fa)continue;
dep[v] = dep[u] + 1;
f[v][0] = u;
for (int i = 1; i <= 18; i++)
f[v][i] = f[f[v][i - 1]][i - 1];
dfs(v, u);
}
}
int lca(int x, int y)
{
if (dep[x] < dep[y])swap(x, y);
int d = dep[x] - dep[y];
for (int i = 18; i >= 0; i--)
if (d & (1<<i))
x = f[x][i];
if (x == y)return x;
for (int i = 18; i >= 0; i--)
if (f[x][i] != f[y][i])
x = f[x][i], y = f[y][i];
return f[x][0];
}
void dfs1(int u, int fa)
{
for (int i = head[u]; i != -1; i = nxt[i])
{
int v = to[i];
if (v == fa)continue;
dfs1(v, u);
c[u] += c[v];
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
mt19937_64 mrand(time(0));
memset(head, -1, sizeof(head));
int n; cin >> n;
for (int i = 1; i <= n; i++)cin >> a[i];
for (int i = 1; i < n; i++)
{
int x, y; cin >> x >> y;
add(x, y), add(y, x);
}
dfs(a[1], -1);
int last = a[1];
for (int i = 2; i <= n; i++)
{
c[a[i]]++; c[last]++;
int l = lca(a[i], last);
c[l]--; c[f[l][0]]--;
last = a[i];
}
dfs1(a[1], -1);
for (int i = 2; i <= n; i++)c[a[i]]--;
for (int i = 1; i <= n; i++)cout << c[i] << '\n';
return 0;
}

浙公网安备 33010602011771号