记录编号 600240 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 雨天的尾巴 最终得分 100
用户昵称 GravatarLikableP 是否通过 通过
代码语言 C++ 运行时间 4.064 s
提交时间 2025-04-22 21:47:10 内存使用 34.62 MiB
显示代码纯文本
#include <cstdio>
#include <algorithm>

const int MAXN = 1e5 + 10;
const int MAXZ = 1e5;

struct EDGE {
	int v, next;
} edge[MAXN << 1];

int edgeNum, head[MAXN];
void AddEdge(int u, int v) {
	edge[++edgeNum].v = v;
	edge[edgeNum].next = head[u];
	head[u] = edgeNum;
}

struct NODE {
	int ls, rs;
	int maxx;
	int type;
} node[MAXN * 17 * 4];

void PushUp(int root) {
	if (node[node[root].ls].maxx >= node[node[root].rs].maxx) {
		node[root].maxx = node[node[root].ls].maxx;
		node[root].type = node[node[root].ls].type;
	} else {
		node[root].maxx = node[node[root].rs].maxx;
		node[root].type = node[node[root].rs].type;
	}
}

int nodeNum;
void AddSingle(int &root, int lt, int rt, int x, int val) {
	if (!root) root = ++nodeNum;
	if (lt == rt) {
		node[root].maxx += val;
		node[root].type = x;
		return ;
	}
	int mid = lt + ((rt - lt) >> 1);
	if (x <= mid) {
		AddSingle(node[root].ls, lt, mid, x, val);
	} else {
		AddSingle(node[root].rs, mid + 1, rt, x, val);
	}
	PushUp(root);
}

int grd[MAXN][20], depth[MAXN];
void dfs(int root, int fa) {
	depth[root] = depth[fa] + 1;
	grd[root][0] = fa;
	for (int i = 1; i <= 19; ++i) {
		grd[root][i] = grd[grd[root][i - 1]][i - 1];
	}
	for (int i = head[root]; i; i = edge[i].next) {
		if (edge[i].v == fa) continue;
		dfs(edge[i].v, root);
	}
}

int LCA(int x, int y) {
	if (depth[x] < depth[y]) {
		::std::swap(x, y);
	}
	for (int i = 19; i >= 0; --i) {
		if (depth[grd[x][i]] >= depth[y]) {
			x = grd[x][i];
		}
	}
	if (x == y) return x;
	for (int i = 19; i >= 0; --i) {
		if (grd[x][i] != grd[y][i]) {
			x = grd[x][i];
			y = grd[y][i];
		}
	}
	return grd[x][0];
}

int Merge(int x, int y, int lt, int rt) {
	if (!x || !y) return x + y;
	if (lt == rt) {
		node[x].maxx += node[y].maxx;
		return x;
	}
	int mid = lt + ((rt - lt) >> 1);
	node[x].ls = Merge(node[x].ls, node[y].ls, lt, mid);
	node[x].rs = Merge(node[x].rs, node[y].rs, mid + 1, rt);
	PushUp(x);
	return x;
}

int n, m; 
int root[MAXN];
int ans[MAXN];

void calc(int now, int fa) {
	for (int i = head[now]; i; i = edge[i].next) {
		if (edge[i].v == fa) continue;
		calc(edge[i].v, now);
		root[now] = Merge(root[now], root[edge[i].v], 1, MAXZ);
	}
	ans[now] = node[root[now]].maxx ? node[root[now]].type : 0;
}

int main() {
	freopen("Rainbows.in", "r", stdin);
	freopen("Rainbows.out", "w", stdout);
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= n - 1; ++i) {
		int u, v;
		scanf("%d %d", &u, &v);
		AddEdge(u, v);
		AddEdge(v, u);
	}
	dfs(1, 0);
	while (m--) {
		int x, y, z, lca;
		scanf("%d %d %d", &x, &y, &z);
		AddSingle(root[x], 1, MAXZ, z, 1);
		AddSingle(root[y], 1, MAXZ, z, 1);
		lca = LCA(x, y);
//		printf("([x]%d,[lca]%d) ([lca]%d,[x]%d)\n", x, lca, lca, x);
		AddSingle(root[lca], 1, MAXZ, z, -1);
		AddSingle(root[grd[lca][0]], 1, MAXZ, z, -1);
	}
	calc(1, 0);
	for (int i = 1; i <= n; ++i) {
		printf("%d\n", ans[i]);
	}
	return 0;
}