题意:
中文
思路:
染色部分树链剖分即可
对于倒数第K次染色,转化为正数第Q次,线段树维护颜色即可。
代码:
#include
using namespace std;
#define ls l,mid,rt*2
#define rs mid+1,r,rt*2+1
#define mi (l+r)/2
const int MAXN = 1e5 + 7;
typedef struct Query {
int u, v, c;
}Query;
vector edge[MAXN];
vector linkk[MAXN];
int n, m, k;
int tsize[MAXN], dep[MAXN], hson[MAXN], father[MAXN];
int order[MAXN], transpos[MAXN];
int belong[MAXN], top[MAXN], cnt;
int tim[MAXN * 4], lazyt[MAXN * 4], lazyT[MAXN * 4], st, en, tmin[MAXN * 4], tmax[MAXN * 4];
int col[MAXN * 4], ans[MAXN];
Query query[MAXN];
void ini() {
for (int i = 1; i <= n; i++) {
edge[i].clear();
belong[i] = 0;
}
linkk[1].clear();
dep[0] = -1;
tsize[0] = 0; cnt = 0; top[1] = 1;
return;
}
void dfs1(int now, int fa) {
father[now] = fa;
int len = edge[now].size();
dep[now] = dep[fa] + 1;
tsize[now] = 1;
hson[now] = 0;
for (int i = 0; i < len; i++) {
int pos = edge[now][i];
if (pos != fa) {
dfs1(pos, now);
tsize[now] += tsize[pos];
if (tsize[pos] > tsize[hson[now]]) hson[now] = pos;
}
}
return;
}
void dfs2(int now, int bel, int fa) {
belong[now] = bel;
linkk[bel].push_back(now);
int len = edge[now].size();
if (hson[now] != 0) dfs2(hson[now], bel, now);
for (int i = 0; i < len; i++) {
int pos = edge[now][i];
if (pos != now && pos != fa && pos != hson[now]) {
cnt++;
linkk[cnt].clear();
top[cnt] = pos;
dfs2(pos, cnt, now);
}
}
return;
}
void build(int l, int r, int rt) {
lazyt[rt] = lazyT[rt] = col[rt] = tim[rt] = 0;
if (l == r) return;
int mid = mi;
build(ls), build(rs);
return;
}
void push_down_t(int rt) {
if (lazyt[rt]) {
tim[rt * 2] += lazyt[rt];
tim[rt * 2 + 1] += lazyt[rt];
lazyt[rt * 2] += lazyt[rt];
lazyt[rt * 2 + 1] += lazyt[rt];
}
lazyt[rt] = 0;
return;
}
void push_up_T(int rt) {
tmin[rt] = min(tmin[rt * 2], tmin[rt * 2 + 1]);
tmax[rt] = max(tmax[rt * 2], tmax[rt * 2 + 1]);
return;
}
void updateT(int l, int r, int rt) {
if (l > en || r < st) return;
if (st <= l && r <= en) {
tim[rt]++;
lazyt[rt]++;
return;
}
int mid = mi;
push_down_t(rt);
updateT(ls), updateT(rs);
return;
}
void makeT(int l, int r, int rt) {
if (l == r) {
tim[rt] -= k;
tmax[rt] = tmin[rt] = max(tim[rt], 0);
return;
}
int mid = mi;
push_down_t(rt);
makeT(ls), makeT(rs);
push_up_T(rt);
return;
}
void solveT(int x, int y) {
while (1) {
if (top[belong[x]] == top[belong[y]]) {
if (dep[x] > dep[y]) swap(x, y);
st = transpos[x], en = transpos[y];
updateT(1, n, 1);
break;
}
else {
if (dep[top[belong[x]]] > dep[top[belong[y]]]) swap(x, y);
st = transpos[top[belong[y]]], en = transpos[y];
updateT(1, n, 1);
y = father[top[belong[y]]];
}
}
return;
}
void push_down_C(int rt) {
if (col[rt]) {
col[rt * 2] = col[rt];
col[rt * 2 + 1] = col[rt];
}
col[rt] = 0;
return;
}
void push_down_T(int rt) {
if (lazyT[rt]) {
tmax[rt * 2] -= lazyT[rt];
tmax[rt * 2 + 1] -= lazyT[rt];
tmin[rt * 2] -=lazyT[rt];
tmin[rt * 2 + 1] -=lazyT[rt];
lazyT[rt * 2] += lazyT[rt];
lazyT[rt * 2 + 1] += lazyT[rt];
}
lazyT[rt] = 0;
return;
}
void updateC(int l, int r, int rt, long long v) {
if (l > en || r < st || tmax[rt] == 0) return;
if (st <= l && r <= en && tmin[rt] > 0) {
col[rt] = v;
return;
}
int mid = mi;
push_down_C(rt);
push_down_T(rt);
updateC(ls, v), updateC(rs, v);
return;
}
void changeT(int l, int r, int rt) {
if (l > en || r < st || tmax[rt] == 0) return;
if (st <= l && r <= en && tmin[rt] > 0) {
tmax[rt]--;
tmin[rt]--;
lazyT[rt]++;
return;
}
int mid = mi;
push_down_T(rt);
changeT(ls), changeT(rs);
push_up_T(rt);
return;
}
void solveC(int x, int y, long long v) {
while (1) {
if (top[belong[x]] == top[belong[y]]) {
if (dep[x] > dep[y]) swap(x, y);
st = transpos[x], en = transpos[y];
updateC(1, n, 1, v);
changeT(1, n, 1);
break;
}
else {
if (dep[top[belong[x]]] > dep[top[belong[y]]]) swap(x, y);
st = transpos[top[belong[y]]], en = transpos[y];
updateC(1, n, 1, v);
changeT(1, n, 1);
y = father[top[belong[y]]];
}
}
return;
}
void makeC(int l, int r, int rt) {
if (l == r) {
ans[l] = col[rt];
return;
}
int mid = mi;
push_down_C(rt);
makeC(ls), makeC(rs);
return;
}
int main() {
scanf("%d%d%d", &n, &m, &k); k--;
ini();
for (int i = 1; i < n; i++) {
int x, y;
scanf("%d%d", &x, &y);
edge[x].push_back(y);
edge[y].push_back(x);
}
dfs1(1, 0);
dfs2(1, ++cnt, 0);
int ppp = 0;
for (int i = 1; i <= cnt; i++) {
int len = linkk[i].size();
for (int j = 0; j < len; j++) {
order[++ppp] = linkk[i][j];
transpos[linkk[i][j]] = ppp;
}
}
build(1, n, 1);
for (int i = 1; i <= m; i++) {
scanf("%d%d%d", &query[i].u, &query[i].v, &query[i].c);
solveT(query[i].u, query[i].v);
}
makeT(1, n, 1);
for (int i = 1; i <= m; i++) {
solveC(query[i].u, query[i].v, query[i].c);
}
makeC(1, n, 1);
for (int i = 1; i <= n; i++) {
printf("%d%c", ans[transpos[i]], " \n"[i == n]);
}
return 0;
}