社区讨论

10分--only AC on11

P4315月下“毛景树”参与者 1已保存回复 0

讨论操作

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

当前回复
0 条
当前快照
1 份
快照标识符
@mk83hfmt
此快照首次捕获于
2026/01/10 17:20
2 个月前
此快照最后确认于
2026/01/13 15:25
2 个月前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
const long long N = 1e5 + 5;
long long n;
vector<long long>graph[N];
long long siz[N], son[N], dep[N], fa[N];
void heavy(long long u, long long Fa, long long Dep) {
	siz[u] = 1;
	fa[u] = Fa;
	dep[u] = Dep;
	long long msiz = 0, mid = 0;
	for (auto i : graph[u]) {
		if (i == Fa)continue;
		heavy(i, u, Dep + 1);
		if (siz[i] > msiz) {
			msiz = siz[i];
			mid = i;
		}
		siz[u] += siz[i];
	}
	son[u] = mid;
}
long long head[N], dfn[N], rnk[N], cnt = 0;
void dfs(long long u, long long Fa, long long Head) {
	head[u] = Head;
	dfn[u] = ++cnt;
	rnk[cnt] = u;
	if (son[u])dfs(son[u], u, Head);
	for (auto i : graph[u]) {
		if (i == Fa || i == son[u])continue;
		dfs(i, u, i);
	}
}
long long tree[N * 4];
long long tag[N * 4];
long long tag1[N * 4];
map<pair<long long, long long>, long long>mp;
void build(long long id, long long l, long long r) {
	if (l == r) {
		tree[id] = mp[ {rnk[l], fa[rnk[l]]}];
		return ;
	}
	long long mid = (l + r) >> 1;
	build(id * 2, l, mid);
	build(id * 2 + 1, mid + 1, r);
	tree[id] = max(tree[id * 2], tree[id * 2 + 1]);
}
void pushdown(long long id, long long l, long long r) {
	if (tag[id] != -1) {
		long long mid = (l + r) >> 1;
		tree[id * 2] = (mid - l + 1) * tag[id];
		tree[id * 2 + 1] = (r - mid) * tag[id];
		tag[id * 2] = tag[id];
		tag1[id * 2] = 0;
		tag[id * 2 + 1] = tag[id];
		tag1[id * 2 + 1] = 0;
		tag[id] = -1;
	}
	if (tag1[id]) {
		long long mid = (l + r) >> 1;
		tree[id * 2] += (mid - l + 1) * tag1[id];
		tree[id * 2 + 1] += (r - mid) * tag1[id];
		tag1[id * 2] += tag1[id];
		tag1[id * 2 + 1] += tag1[id];
		tag1[id] = 0;
	}
}
void up(long long id, long long l, long long r, long long ql, long long qr, long long val) {
	if (ql <= l && r <= qr) {
		tag[id] = val;
		tag1[id] = 0;
		tree[id] = val;
		return ;
	}
	pushdown(id, l, r);
	long long mid = (l + r) >> 1;
	if (ql <= mid)up(id * 2, l, mid, ql, qr, val);
	if (qr > mid)up(id * 2 + 1, mid + 1, r, ql, qr, val);
	tree[id] = max(tree[id * 2 + 1], tree[id * 2]);
}
void up1(long long id, long long l, long long r, long long ql, long long qr, long long val) {
	if (ql <= l && r <= qr) {
		tree[id] += val;
		tag1[id] += val;
		return ;
	}
	pushdown(id, l, r);
	long long mid = (l + r) >> 1;
	if (ql <= mid)up1(id * 2, l, mid, ql, qr, val);
	if (qr > mid)up1(id * 2 + 1, mid + 1, r, ql, qr, val);
	tree[id] = max(tree[id * 2 + 1], tree[id * 2]);
}
void upchain(long long x, long long y, long long z) {
	while (head[x] != head[y]) {
		if (dep[head[x]] < dep[head[y]]) {
			swap(x, y);
		}
		up(1, 1, n, dfn[head[x]], dfn[x], z);
		x = fa[head[x]];
	}
	if (dep[x] > dep[y]) {
		swap(x, y);
	}
	up(1, 1, n, dfn[x] + 1, dfn[y], z);
}
void upchain1(long long x, long long y, long long z) {
	while (head[x] != head[y]) {
		if (dep[head[x]] < dep[head[y]]) {
			swap(x, y);
		}
		up1(1, 1, n, dfn[head[x]], dfn[x], z);
		x = fa[head[x]];
	}
	if (dep[x] > dep[y]) {
		swap(x, y);
	}
	up1(1, 1, n, dfn[x] + 1, dfn[y], z);
}
long long query(long long id, long long l, long long r, long long ql, long long qr) {
	if (ql <= l && r <= qr) {
		return tree[id];
	}
	pushdown(id, l, r);
	long long mid = (l + r) >> 1;
	long long ans = 0;
	if (ql <= mid)ans = max(ans, query(id * 2, l, mid, ql, qr));
	if (qr > mid)ans = max(ans, query(id * 2 + 1, mid + 1, r, ql, qr));
	return ans;
}
long long querychain(long long x, long long y) {
	long long ans = 0;
	while (head[x] != head[y]) {
		if (dep[head[x]] < dep[head[y]]) {
			swap(x, y);
		}
		ans = max(ans, query(1, 1, n, dfn[head[x]], dfn[x]));
		x = fa[head[x]];
	}
	if (dep[x] > dep[y]) {
		swap(x, y);
	}
	ans = max(ans, query(1, 1, n, dfn[x] + 1, dfn[y]));
	return ans;
}
vector<pair<long long, long long>>side;
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	for (long long i = 1; i <= N * 4; i++) {
		tag[i] = -1;
	}
	cin >> n;
	for (long long i = 1; i < n; i++) {
		long long u, v, w;
		cin >> u >> v >> w;
		graph[u].push_back(v);
		graph[v].push_back(u);
		mp[ {u, v}] = w;
		mp[ {v, u}] = w;
		side.push_back({u, v});
	}
	heavy(1, 0, 1);
	dfs(1, 0, 1);
	build(1, 1, n);
	string op;
	while (cin >> op) {
		if (op == "Stop")break;
		long long x, y;
		cin >> x >> y;
		if (op == "Change") {
			long long a = side[x - 1].first, b = side[x - 1].second;
			if (fa[a] == b) {
				swap(a, b);
			}
			up(1, 1, n, fa[dfn[b]], dfn[b], y);
		} else if (op == "Cover") {
			long long z;
			cin >> z;
			upchain(x, y, z);
		} else if (op == "Add") {
			long long z;
			cin >> z;
			upchain1(x, y, z);
		} else {
			cout << querychain(x, y) << '\n';
		}
	}
	return 0;
}

回复

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

正在加载回复...