传送门雨天的尾巴。这样写可以过前5个点,然后WA一排,再TLE一排QAQ是常数太大了吗……WA也不知道是为什么QAQ
做法就是对每个点动态开点权值线段树标记每个颜色,树上差分标记后线段树合并再查询最大值的颜色。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define maxn 100005
using namespace std;
typedef long long ll;
const int mx = 1e5;
int read() {
int x = 0, f = 1, ch = getchar();
while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
while(isdigit(ch)) x = (x << 1) + (x << 3) + ch - '0', ch = getchar();
return x * f;
}
struct edge {int to, nxt;} e[maxn << 1];
int head[maxn], k = 0;
void add(int u, int v) {e[k] = {v, head[u]}; head[u] = k++;}
int n, m;
int lg2[maxn], fa[maxn][20], dep[maxn];
void dfs(int u) {
for(int i = 1; (1 << i) <= dep[u]; i++) fa[u][i] = fa[fa[u][i - 1]][i - 1];
for(int i = head[u], v; ~i; i = e[i].nxt) {
v = e[i].to; if(v == fa[u][0]) continue;
fa[v][0] = u; dep[v] = dep[u] + 1;
dfs(v);
}
}
int LCA(int u, int v) {
if(dep[u] > dep[v]) swap(u, v);
while(dep[u] < dep[v]) v = fa[v][lg2[dep[v] - dep[u]] - 1];
if(u == v) return u;
for(int i = lg2[dep[u]]; i >= 0; i--)
if(fa[u][i] != fa[v][i]) u = fa[u][i], v = fa[v][i];
return fa[u][0];
}
struct TREE {int l, r, x;} t[maxn << 6];
int tot, ans[maxn];
void change(int p, int l, int r, int x, int val) {
if(l == r) {t[p].x += val; return;}
register int mid = l + r >> 1;
if(x <= mid) {if(!t[p].l) t[p].l = ++tot; change(t[p].l, l, mid, x, val);}
else {if(!t[p].r) t[p].r = ++tot; change(t[p].r, mid + 1, r, x, val);}
t[p].x = max(t[t[p].l].x, t[t[p].r].x);
}
int merge(int p, int q, int l, int r) {
// printf("now:%d to %d\n", l, r);
if(!p) return q; if(!q) return p;
if(l == r) {t[p].x += t[q].x; return p;}
register int mid = l + r >> 1;
t[p].l = merge(t[p].l, t[q].l, l, mid);
t[p].r = merge(t[p].r, t[q].r, mid + 1, r);
t[p].x = max(t[t[p].l].x, t[t[p].r].x);
return p;
}
int ask(int p, int l, int r) {
// printf("now:%d to %d\n", l, r);
if(l == r) {if(t[p].x) return l; return 0;}
register int mid = l + r >> 1;
if(t[t[p].l].x == t[p].x) return ask(t[p].l, l, mid);
else return ask(t[p].r, mid + 1, r);
}
void dfs2(int u) {
for(int i = head[u], v; ~i; i = e[i].nxt) {
v = e[i].to; if(v == fa[u][0]) continue;
dfs2(v);
merge(u, v, 1, mx);
}
ans[u] = ask(u, 1, mx);
}
signed main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
n = read(), m = read(); memset(head, -1, sizeof head);
for(int i = 1, u, v; i < n; i++) u = read(), v = read(), add(u, v), add(v, u);
for(int i = 1; i <= n; i++) lg2[i] = lg2[i << 1] + 1;
dfs(1); tot = n;
for(int i = 1, u, v, w, lca; i <= m; i++) {
u = read(), v = read(), w = read(); lca = LCA(u, v);
change(u, 1, mx, w, 1), change(v, 1, mx, w, 1), change(lca, 1, mx, w, -1), change(fa[lca][0], 1, mx, w, -1);
}
dfs2(1);
for(int i = 1; i <= n; i++) printf("%d\n", ans[i]);
return 0;
}