10 pts 求调
查看原帖
10 pts 求调
415592
Anxiomgh楼主2023/7/21 15:14

RT,不胜感激。

#include<cstdio>
#include<iostream>
#include<algorithm>

using namespace std;
#define ll long long

inline int read()
{
	int x = 0, f = 1; char ch = getchar();
	while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - 48; ch = getchar(); }
	return x * f;
}
const int MAXN = 1e5 + 10;
struct edge
{
	int nxt, to;
};
int head[MAXN], cnt; edge e[MAXN << 1];
void add_edge(int u, int v)
{
	e[++cnt].nxt = head[u];
	head[u] = cnt;
	e[cnt].to = v; 
}
int tot, root[MAXN], anc[MAXN][23], dep[MAXN], ans[MAXN];
struct segmentTree
{
	int u, val, ls, rs;
}tr[MAXN * 50];

void push_up(int x)
{
	if (tr[tr[x].ls].val >= tr[tr[x].rs].val) 
		tr[x].u = tr[tr[x].ls].u, tr[x].val = tr[tr[x].ls].val;
	else tr[x].u = tr[tr[x].rs].u, tr[x].val = tr[tr[x].rs].val;
}
void update(int &x, int p, int f, int l = 0, int r = 1e5)
{
	if (!x) x = ++tot;
	if (l == r)
	{
		tr[x].u = p; tr[x].val += f;
		return;
	}
	int mid = (l + r) >> 1;
	if (p <= mid) update(tr[x].ls, p, f, l, mid);
	else update(tr[x].rs, p, f, mid + 1, r);
	push_up(x);
}
int merge(int a, int b, int l = 0, int r = 1e5) // 将 b 合并到 a 
{
	if (!a) return b;
	if (!b) return a;
	if (l == r)
	{
		tr[a].val += tr[b].val;
		return a;
	}
	int mid = (l + r) >> 1;
	tr[a].ls = merge(tr[a].ls, tr[b].ls, l, mid);
	tr[a].rs = merge(tr[a].rs, tr[b].rs, mid + 1, r);
	push_up(a);
	return a;
} 
void dfs1(int x, int fa)
{
	for (int i = head[x]; i; i = e[i].nxt)
	{
		int v = e[i].to;
		if (v == fa) continue;
		dfs1(v, x);
		root[x] = merge(root[x], root[v]);
	}
	ans[x] = tr[root[x]].u;
	if (tr[root[x]].val == 0) ans[x] = 0;
}

void dfs2(int x, int fa, int d)
{
	dep[x] = d;
	for (int i = 1; i <= 20; i++)
		anc[x][i] = anc[anc[x][i - 1]][i - 1];
	for (int i = head[x]; i; i = e[i].nxt)
	{
		int v = e[i].to;
		if (v == fa) continue;
		anc[v][0] = x;
		dfs2(v, x, d + 1);
	}
}
int LCA(int x, int y)
{
	if (dep[x] > dep[y])
		swap(dep[x], dep[y]); // x 深度小,y 深度大 
	int tmp = dep[y] - dep[x];
	for (int i = 20; i >= 0; i--) // 跳 y 
		if (tmp & (1 << i)) y = anc[y][i];
	if (x == y) return x;
	for (int i = 20; i >= 0; i--)
		if (anc[x][i] != anc[y][i]) 
			x = anc[x][i], y = anc[y][i];
	return anc[x][0];
}
int main()
{
	int n, m;
	n = read(); m = read();
	for (int i = 2; i <= n; i++)
	{
		int a, b;
		a = read(); b = read();
		add_edge(a, b); add_edge(b, a);
	}
	dfs2(1, 0, 0);
	while (m--)
	{
		int x, y, z, lca;
		x = read(); y = read(); z = read();
		lca = LCA(x, y);
		update(root[x], z, 1); update(root[y], z, 1);
		update(root[lca], z, -1); update(root[anc[lca][0]], z, -1);
	}
	dfs1(1, 0);
	for (int i = 1; i <= n; i++)
		printf("%d\n", ans[i]);
	return 0;
}
2023/7/21 15:14
加载中...