题目链接:https://www.nowcoder.com/acm/contest/206/I
题目大意:中文题面,自行自会~ —,—。
题目思路:题目要求在树上进行一条链的更新操作,很直观就能想到用树链剖分来做。本题要求的是每个结点倒数第k次被染色时,是被染成了什么颜色,由于这个k是固定的,所以我们可以用线段树来维护每个点被更新的次数,维护一条链上的节点被更新过的次数的最大次数。当一个区间的最大被更新次数超过k时,我们再暴力往下去找具体区间,对答案进行更新,对一个节点的答案更新完之后就将其的值设为负无穷大。由于每个点算答案的时候都只会被算到一次,所以整体的复杂度应该是 O(n*logn*logn)。(因为题目是要求倒数第k大,所以更新的时候从后往前更新就行了,问题不大)
具体实现看代码:
#include <bits/stdc++.h>
#define fi first
#define se second
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define pb push_back
#define MP make_pair
#define lowbit(x) x&-x
#define clr(a) memset(a,0,sizeof(a))
#define _INF(a) memset(a,0x3f,sizeof(a))
#define FIN freopen("in.txt","r",stdin)
#define IOS ios::sync_with_stdio(false)
#define fuck(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int>pii;
typedef pair<ll, ll>pll;
typedef pair<double, int> pdi;
const int mod = 998244353;
const int MX = 1e5 + 7;
const int inf = 0x3f3f3f3f;
int n, m, k;
int MAX[MX << 2], add[MX << 2];
int ans[MX];
int fa[MX], dep[MX], id[MX], idx[MX], son[MX], top[MX], sz[MX], tot;
vector<int>E[MX];
void push_up(int rt) {
MAX[rt] = max(MAX[rt << 1], MAX[rt << 1 | 1]);
}
void push_down(int rt) {
if (add[rt]) {
add[rt << 1] += add[rt];
add[rt << 1 | 1] += add[rt];
MAX[rt << 1] += add[rt];
MAX[rt << 1 | 1] += add[rt];
add[rt] = 0;
}
}
void dfs(int l, int r, int rt, int d) {
if (MAX[rt] < k) return;
if (l == r) {
MAX[rt] = -inf;
ans[idx[l]] = d;
return;
}
push_down(rt);
int m = (l + r) >> 1;
dfs(lson, d); dfs(rson, d);
push_up(rt);
}
void update(int L, int R, int d, int l, int r, int rt) {
if (L <= l && r <= R) {
MAX[rt]++; add[rt]++;
dfs(l, r, rt, d);
return;
}
push_down(rt);
int m = (l + r) >> 1;
if (L <= m) update(L, R, d, lson);
if (R > m) update(L, R, d, rson);
push_up(rt);
}
void dfs1(int u) {
sz[u] = 1; son[u] = 0;
for (auto v : E[u]) {
if (v == fa[u]) continue;
fa[v] = u; dep[v] = dep[u] + 1;
dfs1(v);
sz[u] += sz[v];
if (sz[v] > sz[son[u]]) son[u] = v;
}
}
void dfs2(int u, int tp) {
id[u] = ++tot; idx[tot] = u;
top[u] = tp;
if (son[u]) dfs2(son[u], tp);
for (auto v : E[u]) {
if (v == fa[u] || v == son[u]) continue;
dfs2(v, v);
}
}
void pre_solve() {
dfs1(1);
dfs2(1, 1);
}
void Update(int u, int v, int d) {
while (top[u] != top[v]) {
if (dep[top[u]] < dep[top[v]]) swap(u, v);
update(id[top[u]], id[u], d, 1, n, 1);
u = fa[top[u]];
}
if (dep[u] > dep[v]) swap(u, v);
update(id[u], id[v], d, 1, n, 1);
}
struct Que {
int u, v, c;
} q[MX];
int main() {
//FIN;
scanf("%d%d%d", &n, &m, &k);
for (int i = 1; i < n; i++) {
int u, v;
scanf("%d%d", &u, &v);
E[u].pb(v); E[v].pb(u);
}
pre_solve();
for (int i = 1; i <= m; i++) scanf("%d%d%d", &q[i].u, &q[i].v, &q[i].c);
for (int i = m; i >= 1; i--) Update(q[i].u, q[i].v, q[i].c);
for (int i = 1; i <= n; i++)
printf("%d%c", ans[i], i == n ? '\n' : ' ');
return 0;
}