- 线段树合并
luogu P4556
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
namespace IO {
template<class T>
void _R(T &x) { cin >> x; }
void _R(int &x) { scanf("%d", &x); }
void _R(ll &x) { scanf("%lld", &x); }
void _R(double &x) { scanf("%lf", &x); }
void _R(char &x) { x = getchar(); }
void _R(char *x) { scanf("%s", x); }
void R() {}
template<class T, class... U>
void R(T &head, U &... tail) { _R(head), R(tail...); }
template<class T>
void _W(const T &x) { cout << x; }
void _W(const int &x) { printf("%d", x); }
void _W(const ll &x) { printf("%lld", x); }
void _W(const double &x) { printf("%.16f", x); }
void _W(const char &x) { putchar(x); }
void _W(const char *x) { printf("%s", x); }
template<class T, class U>
void _W(const pair<T, U> &x) { _W(x.first), putchar(' '), _W(x.second); }
template<class T>
void _W(const vector<T> &x) { for (auto i = x.begin(); i != x.end(); _W(*i++)) if (i != x.cbegin()) putchar(' '); }
void W() {}
template<class T, class... U>
void W(const T &head, const U &... tail) { _W(head), putchar(sizeof...(tail) ? ' ' : '\n'), W(tail...); }
}
using namespace IO;
template <typename T> T pow(T a, long long b) {
assert(b >= 0);
T r = 1; while (b) { if (b & 1) r *= a; b >>= 1; a *= a; } return r;
}
const int maxn = 1e5+2;
const int maxp = 2e5*32+50;
int tot = 0, n, m;
int ls[maxp], rs[maxp], mx[maxp], c[maxp];
void pushup(int x) {
if (mx[ls[x]] >= mx[rs[x]]) {
mx[x] = mx[ls[x]];
c[x] = c[ls[x]];
} else {
mx[x] = mx[rs[x]];
c[x] = c[rs[x]];
}
}
void insert(int &x, int l, int r, int y, int k) {
if (!x) x = ++tot;
if (l == r) {
mx[x] += k;
c[x] = l;
return;
}
int mid = l + r >> 1;
if (y <= mid) insert(ls[x], l, mid, y, k);
else insert(rs[x], mid + 1, r, y, k);
pushup(x);
}
void merge(int &x, int y, int l, int r) {
if (!x) {
x = y;
return;
}
if (!y) return;
if (l == r) {
c[x] = l;
mx[x] += mx[y];
return;
}
int mid = l + r >> 1;
merge(ls[x], ls[y], l, mid);
merge(rs[x], rs[y], mid + 1, r);
pushup(x);
}
vector<int> e[maxn];
int fa[maxn][22], dep[maxn];
void predo(int u, int pre, int dp) {
fa[u][0] = pre;
dep[u] = dp;
for (int i = 1; i < 22; ++i) fa[u][i] = fa[fa[u][i - 1]][i - 1];
for (auto v : e[u]) {
if (v == pre) continue;
predo(v, u, dp + 1);
}
}
int lca(int u, int v) {
if (dep[u] < dep[v]) swap(u, v);
int d = dep[u] - dep[v];
for (int i = 0; (1 << i) <= d; ++i)
if (d >> i & 1) u = fa[u][i];
if (u == v) return u;
for (int i = 21; i >= 0; --i) {
if (fa[u][i] != fa[v][i]) u = fa[u][i], v = fa[v][i];
}
return fa[u][0];
}
void dfs(int u, int pre) {
for (auto v : e[u]) {
if (v == pre) continue;
dfs(v, u);
merge(u, v, 1, maxn);
}
}
int main() {
R(n, m);
for (int i = 1; i < n; ++i) {
int u, v; R(u, v);
e[u].push_back(v);
e[v].push_back(u);
}
tot = n;
predo(1, 0, 1);
while (m--) {
int x, y, z; R(x, y, z);
insert(x, 1, maxn, z, 1);
insert(y, 1, maxn, z, 1);
int xy = lca(x, y);
insert(xy, 1, maxn, z, -1);
if (xy != 1) insert(fa[xy][0], 1, maxn, z, -1);
}
dfs(1, 0);
for (int i = 1; i <= n; ++i) W(mx[i] == 0 ? 0 : c[i]);
return 0;
}