不胜感激
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 9, LOGN = 22;
struct Edge{
int v, nex;
} e[N << 1];
int head[N], ecnt;
void addEdge(int u, int v){
e[++ecnt] = Edge{v, head[u]};
head[u] = ecnt;
}
struct Node{
int ls, rs, sum, res;
} t[50 * N];
int ans[N], cnt;
//线段树pushup
void update(int x){
if(t[t[x].ls].sum < t[t[x].rs].sum) {
t[x].res = t[t[x].rs].res;
t[x].sum = t[t[x].rs].sum;
} else {
t[x].res = t[t[x].ls].res;
t[x].sum = t[t[x].ls].sum;
}
}
//线段树合并
int modify(int a, int b, int l, int r) {
if(!a)
return b;
if(!b)
return a;
if(l == r) {
t[a].sum += t[b].sum;
return a;
}
int mid = (l + r) >> 1;
t[a].ls = modify(t[a].ls, t[b].ls, l, mid);
t[a].rs = modify(t[a].rs, t[b].rs, mid + 1, r);
update(a);
return a;
}
//动态开点线段树
int Build(int id, int l, int r, int co, int z) {
if(!id)
id = ++cnt;
if(l == r) {
t[id].sum += z;
t[id].res = co;
return id;
}
int mid = (l + r) >> 1;
if(co <= mid)
t[id].ls = Build(t[id].ls, l, mid, co, z);
else
t[id].rs = Build(t[id].rs, mid + 1, r, co, z);
update(id);
return id;
}
int fa[N][LOGN], dep[N], rt[N];
//求每个节点的深度和父亲
void dfs1(int u, int fat){
for(int i = head[u]; i; i = e[i].nex){
int v = e[i].v;
if(v != fat){
fa[v][0] = u;
dep[v] = dep[u] + 1;
dfs1(v, u);
}
}
}
//求最近公共祖先
int query(int x, int y){
if(dep[x] > dep[y])
swap(x, y);
int d = dep[y] - dep[x];
int t = 0;
while(d){
if(d & 1)
y = fa[y][t];
++t;
d >>= 1;
}
t = 0;
while(fa[x][t] != fa[y][t])
++t;
--t;
while(t >= 0){
if(fa[x][t] != fa[y][t]){
x = fa[x][t];
y = fa[y][t];
}
--t;
}
if(x != y){
x = fa[x][0];
y = fa[y][0];
}
return x;
}
//树上前缀和
void dfs2(int u) {
for(int i = head[u]; i; i = e[i].nex) {
int v = e[i].v;
if(v == fa[u][0])
continue;
dfs2(v);
rt[u] = modify(rt[u], rt[v], 1, 100000);
}
ans[u] = t[rt[u]].res;
if(t[rt[u]].sum == 0)
ans[u] = 0;
}
int n, m;
int main(){
scanf("%d%d", &n, &m);
for(int i = 1; i < n; i++){
int u, v;
scanf("%d%d", &u, &v);
addEdge(u, v);
addEdge(v, u);
}
fa[1][0] = 1;
dfs1(1, 1);
for(int j = 1, j2 = 2; j2 <= n; ++j, j2 <<= 1)
for(int i = 1; i <= n; ++i)
fa[i][j] = fa[fa[i][j - 1]][j - 1];
for(int i = 1; i <= m; i++){
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
int lca = query(x, y);
//树上差分
rt[x] = Build(rt[x], 1, 100000, z, 1);
rt[y] = Build(rt[y], 1, 100000, z, 1);
rt[lca] = Build(rt[lca], 1, 100000, z, -1);
rt[fa[lca][0]] = Build(rt[fa[lca][0]], 1, 100000, z, -1);
}
dfs2(1);
for(int i = 1; i <= n; i++)
printf("%d\n", ans[i]);
return 0;
}