社区讨论

5pts求助

P4556【模板】线段树合并 / [Vani 有约会] 雨天的尾巴参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lvz9ywoz
此快照首次捕获于
2024/05/09 21:19
2 年前
此快照最后确认于
2024/05/10 09:09
2 年前
查看原帖
RT,动态开点线段树求调
CPP
#include<bits/stdc++.h>
using namespace std;
int n, m;
int x[100010], y[100010], z[100010], maxn;
struct edge {
	int u, v, next;
} e[100010];
int head[100010], num_edge;
void add_edge(int u, int v) {
	num_edge++;
	e[num_edge].u = u;
	e[num_edge].v = v;
	e[num_edge].next = head[u];
	head[u] = num_edge;
}
int f[100010][20], d[100010], l;
void dfs(int a, int fa) {
	f[a][0] = fa;
	d[a] = d[fa] + 1;
	for (int i = 1; i <= l; i++) {
		f[a][i] = f[f[a][i - 1]][i - 1];
	}
	for (int i = head[a]; i != 0; i = e[i].next) {
		if (e[i].v != fa)dfs(e[i].v, a);
	}
}
int lca(int a, int b) {
	if (d[a] < d[b])swap(a, b);
	for (int i = l; i >= 0; i--) {
		if (d[f[a][i]] >= b)a = f[a][i];
	}
	if (a == b)return a;
	for (int i = l; i >= 0; i--) {
		if (f[a][i] != f[b][i]) {
			a = f[a][i];
			b = f[b][i];
		}
	}
	return f[a][0];
}
struct node {
	int l, r;
	int max, v;
};
vector<node>nd;
int h[100010];
int build() {
	node d;
	d.l = d.r = 0;
	d.max = d.v = 0;
	nd.push_back(d);
	return nd.size() - 1;
}
void add(int a, int c, int l, int r, int k) {
	if (l == r && l == c) {
		nd[a].max += k;
		nd[a].v = c;
		return;
	}
	int mid = (l + r) >> 1;
	if (c <= mid) {
		if (nd[a].l == 0)nd[a].l = build();
		add(nd[a].l, c, l, mid, k);
	} else {
		if (nd[a].r == 0)nd[a].r = build();
		add(nd[a].r, c, mid + 1, r, k);
	}
	if (nd[nd[a].l].max >= nd[nd[a].r].max) {
		nd[a].max = nd[nd[a].l].max;
		nd[a].v = nd[nd[a].l].v;
	} else {
		nd[a].max = nd[nd[a].r].max;
		nd[a].v = nd[nd[a].r].v;
	}
}
int merge(int a, int b, int l, int r) {
	if (a == 0)return b;
	if (b == 0)return a;
	if (l == r) {
		nd[a].max += nd[b].max;
		return a;
	}
	int mid = (l + r) >> 1;
	int ls = merge(nd[a].l, nd[b].l, l, mid);
	int rs = merge(nd[a].r, nd[b].r, mid + 1, r);
	if (nd[ls].max >= nd[rs].max) {
		nd[a].max = nd[ls].max;
		nd[a].v = nd[ls].v;
	} else {
		nd[a].max = nd[rs].max;
		nd[a].v = nd[rs].v;
	}
	nd[a].l = ls;
	nd[a].r = rs;
	return a;
}
void dfss(int a, int fa) {
	for (int i = head[a]; i != 0; i = e[i].next) {
		if (e[i].v == fa)continue;
		dfss(e[i].v, a);
		h[a] = merge(h[a], h[e[i].v], 1, maxn);
	}
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> m;
	l = ceil(log2(n));
	for (int i = 1; i < n; i++) {
		int a, b;
		cin >> a >> b;
		add_edge(a, b);
		add_edge(b, a);
	}
	dfs(1, 0);
	build();
	nd[0].max = INT_MIN;
	for (int i = 1; i <= n; i++)h[i] = build();
	for (int i = 1; i <= m; i++) {
		cin >> x[i] >> y[i] >> z[i];
		maxn = max(maxn, z[i]);
	}
	for (int i = 1; i <= m; i++) {
		int ff = lca(x[i], y[i]);
		add(h[f[ff][0]], z[i], 1, maxn, -1);
		add(h[ff], z[i], 1, maxn, -1);
		add(x[i], z[i], 1, maxn, 1);
		add(y[i], z[i], 1, maxn, 1);
	}
	dfss(1, 0);
	for (int i = 1; i <= n; i++) {
		cout << nd[h[i]].v << '\n';
	}
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...