10pts https://www.luogu.com.cn/record/128754217
可爱代码如下(实在条不出来 /kel 球各位大佬帮条)
/* No.2 数据
10 10
2 1
3 2
4 3
5 3
6 3
7 4
8 5
9 8
10 3
6 2 6
3 2 6
3 3 2
6 6 6
10 3 3
10 7 1
3 7 4
7 9 5
4 2 4
3 3 6
0
6
6
4
5
6
1
5
5
1
我的输出 第一行为 6 而不是答案中的 0 /dk
*/
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, I = 1e5;
int n, m, u, v, z, cnt, res[N], d[N], rt[N], fa[22][N];
struct {
int v, l, r, x;
} tr[N << 6];
vector<int> g[N];
void dfs0(int u) {
for (int i = 0; i <= 20; i++)
fa[i + 1][u] = fa[i][fa[i][u]];
for (int i : g[u])
if (i != fa[0][u]) {
fa[0][i] = u;
d[i] = d[u] + 1;
dfs0(i);
}
}
void pushup(int u) {
if (tr[tr[u].l].v >= tr[tr[u].r].v)
tr[u].v = tr[tr[u].l].v,
tr[u].x = tr[tr[u].l].x;
else
tr[u].v = tr[tr[u].r].v,
tr[u].x = tr[tr[u].r].x;
}
void update(int &u, int l, int r, int x, int v) {
if (!u) u = ++cnt;
if (l == r)
tr[u].v += v, tr[u].x = x;
else {
int mid = l + r >> 1;
if (x <= mid)
update(tr[u].l, l, mid, x, v);
else
update(tr[u].r, mid + 1, r, x, v);
pushup(u);
}
}
int merge(int u, int v, int l, int r) {
if (!u) return v;
if (!v) return u;
if (l == r)
return tr[u].v += tr[v].v, u;
int mid = l + r >> 1;
tr[u].l = merge(tr[u].l, tr[v].l, l, mid);
tr[u].r = merge(tr[u].r, tr[v].r, mid + 1, r);
return pushup(u), u;
}
int lca(int u, int v) {
if (d[u] < d[v])
swap(u, v);
int dif = d[v] - d[u];
for (int i = 0; 1 << i <= dif; i++)
if (1 << i & dif) v = fa[i][v];
if (u == v) return u;
for (int i = 20; ~i; i--)
if (fa[i][u] != fa[i][v]) u = fa[i][u], v = fa[i][v];
return fa[0][u];
}
void dfs(int u) {
for (int i : g[u])
if (i != fa[0][u]) {
dfs(i);
rt[u] = merge(rt[u], rt[i], 1, I);
}
res[u] = tr[rt[u]].x;
if (!tr[rt[u]].v) res[u] = 0;
}
int main() {
cin >> n >> m;
for (int i = n; --i;) {
cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs0(1);
while (m--) {
cin >> u >> v >> z;
update(rt[u], 1, I, z, 1);
update(rt[v], 1, I, z, 1);
int w = lca(u, v);
update(rt[w], 1, I, z, -1);
update(rt[fa[0][w]], 1, I, z, -1);
}
dfs(1);
for (int i = 1; i <= n; i++)
cout << res[i] << '\n';
}