牛客国庆集训派对Day6 I 清明梦超能力者黄YY

版权声明:欢迎转载,请注明出处噢,谢谢 https://blog.csdn.net/DT2131/article/details/82953788

题意:

          中文

思路:

         染色部分树链剖分即可

         对于倒数第K次染色,转化为正数第Q次,线段树维护颜色即可。

代码:

#include <bits/stdc++.h>
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 <int> edge[MAXN];
vector <int> 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;
}

猜你喜欢

转载自blog.csdn.net/DT2131/article/details/82953788