【悬 2~3 关】线段树合并板子可爱代码10pts求条
查看原帖
【悬 2~3 关】线段树合并板子可爱代码10pts求条
912750
CarrotMeow楼主2023/10/11 17:35

10pts https://www.luogu.com.cn/record/128754217

可爱代码如下(实在条不出来 /kel 球各位大佬帮条)

/* No.2 数据
10 10 
2 1 
3 2 
4 3 
5 3 
6 3 
7 4 
8 5 
9 8 
10 3 
6 2 6 
3 2 6 
3 3 2 
6 6 6 
10 3 3 
10 7 1 
3 7 4 
7 9 5 
4 2 4 
3 3 6

0
6
6
4
5
6
1
5
5
1
我的输出 第一行为 6 而不是答案中的 0 /dk
*/
#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 10, I = 1e5;
int n, m, u, v, z, cnt, res[N], d[N], rt[N], fa[22][N];
struct {
    int v, l, r, x;
} tr[N << 6];
vector<int> g[N];

void dfs0(int u) {
    for (int i = 0; i <= 20; i++)
        fa[i + 1][u] = fa[i][fa[i][u]];
    for (int i : g[u])
        if (i != fa[0][u]) {
            fa[0][i] = u;
            d[i] = d[u] + 1;
            dfs0(i);
        }
}

void pushup(int u) {
    if (tr[tr[u].l].v >= tr[tr[u].r].v)
        tr[u].v = tr[tr[u].l].v,
        tr[u].x = tr[tr[u].l].x;
    else
        tr[u].v = tr[tr[u].r].v,
        tr[u].x = tr[tr[u].r].x;
}

void update(int &u, int l, int r, int x, int v) {
    if (!u) u = ++cnt;
    if (l == r)
        tr[u].v += v, tr[u].x = x;
    else {
        int mid = l + r >> 1;
        if (x <= mid)
            update(tr[u].l, l, mid, x, v);
        else
            update(tr[u].r, mid + 1, r, x, v);
        pushup(u);
    }
}

int merge(int u, int v, int l, int r) {
	if (!u) return v;
	if (!v) return u;
	if (l == r)
		return tr[u].v += tr[v].v, u;
	int mid = l + r >> 1;
	tr[u].l = merge(tr[u].l, tr[v].l, l, mid);
	tr[u].r = merge(tr[u].r, tr[v].r, mid + 1, r);
	return pushup(u), u;
}

int lca(int u, int v) {
	if (d[u] < d[v])
		swap(u, v);
    int dif = d[v] - d[u];
    for (int i = 0; 1 << i <= dif; i++)
        if (1 << i & dif) v = fa[i][v];
    if (u == v) return u;
    for (int i = 20; ~i; i--)
        if (fa[i][u] != fa[i][v]) u = fa[i][u], v = fa[i][v];
    return fa[0][u];
}

void dfs(int u) {
	for (int i : g[u])
		if (i != fa[0][u]) {
			dfs(i);
			rt[u] = merge(rt[u], rt[i], 1, I);
		}
	res[u] = tr[rt[u]].x;
	if (!tr[rt[u]].v) res[u] = 0;
}

int main() {
	cin >> n >> m;
	for (int i = n; --i;) {
		cin >> u >> v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	dfs0(1);
	while (m--) {
		cin >> u >> v >> z;
		update(rt[u], 1, I, z, 1);
		update(rt[v], 1, I, z, 1);
		int w = lca(u, v);
		update(rt[w], 1, I, z, -1);
		update(rt[fa[0][w]], 1, I, z, -1);
	}
	dfs(1);
	for (int i = 1; i <= n; i++)
		cout << res[i] << '\n';
}
2023/10/11 17:35
加载中...