社区讨论

84分求助-170行

P1505[国家集训队] 旅游参与者 1已保存回复 0

讨论操作

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

当前回复
0 条
当前快照
1 份
快照标识符
@mk2mywd2
此快照首次捕获于
2026/01/06 21:39
2 个月前
此快照最后确认于
2026/01/06 21:57
2 个月前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5 + 5;
int fa[N], son[N], head[N];
int siz[N], dep[N], dfn[N], rnk[N];
vector<int>graph[N];
map<pair<int, int>, int>mp;
int n;
void heavy(int u, int Fa, int Dep) {
	siz[u] = 1;
	fa[u] = Fa;
	dep[u] = Dep;
	int msiz = 0, mid = 0;
	for (auto v : graph[u]) {
		if (v == Fa)continue;
		heavy(v, u, Dep + 1);
		if (siz[v] > msiz) {
			msiz = siz[v];
			mid = v;
		}
		siz[u] += siz[v];
	}
	son[u] = mid;
}
int cnt = 0;
void dfs(int u, int Fa, int Head) {
	dfn[u] = ++cnt;
	rnk[cnt] = u;
	head[u] = Head;
	if (son[u])dfs(son[u], u, Head);
	for (auto v : graph[u]) {
		if (v == Fa || v == son[u])continue;
		dfs(v, u, v);
	}
}
struct node {
	int sum = 0, ma = -1001, mi = 1001;
} tree[N * 4];
int tag[N * 4];
node operator+(node a, node b) {
	return {a.sum + b.sum, max(a.ma, b.ma), min(a.mi, b.mi)};
}
void build(int id, int l, int r) {
	if (l == r) {
		int w = mp[ {rnk[l], fa[rnk[l]]}];
		if (fa[rnk[l]])tree[id] = {w, w, w};
		return ;
	}
	int mid = (l + r) >> 1;
	build(id * 2, l, mid);
	build(id * 2 + 1, mid + 1, r);
	tree[id] = tree[id * 2] + tree[id * 2 + 1];
}
void pushdown(int id) {
	if (tag[id] == -1) {
		tree[id * 2] = {-1 * tree[id * 2].sum, -1 * tree[id * 2].mi, -1 * tree[id * 2].ma};
		tag[id * 2] = -1 * tag[id * 2];
		tree[id * 2 + 1] = {-1 * tree[id * 2 + 1].sum, -1 * tree[id * 2 + 1].mi, -1 * tree[id * 2 + 1].ma};
		tag[id * 2 + 1] = -1 * tag[id * 2 + 1];
		tag[id] = 1;
	}
}
node query(int id, int l, int r, int ql, int qr) {
	if (ql <= l && r <= qr) {
		return tree[id];
	}
	pushdown(id);
	int mid = (l + r) >> 1;
	node res = {0, -1001, 1001};
	if (ql <= mid)res = res + query(id * 2, l, mid, ql, qr);
	if (qr > mid)res = res + query(id * 2 + 1, mid + 1, r, ql, qr);
	return res;
}
void up(int id, int l, int r, int ql, int qr, int val) {
	if (ql <= l && r <= qr) {
		if (val != -1) {
			tree[id] = {val, val, val};
		} else {
			tag[id] = -1 * tag[id];
			tree[id] = {-1 * tree[id].sum, -1 * tree[id].mi, -1 * tree[id].ma};
		}
		return ;
	}
	pushdown(id);
	int 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] = tree[id * 2] + tree[id * 2 + 1];
}
node querychain(int x, int y) {
	node res = {0, -1001, 1001};
	while (head[x] != head[y]) {
		if (dep[head[x]] < dep[head[y]]) {
			swap(x, y);
		}
		res = res + query(1, 1, n, dfn[head[x]], dfn[x]);
		x = fa[head[x]];
	}
	if (dep[x] > dep[y]) {
		swap(x, y);
	}
	res = res + query(1, 1, n, dfn[x] + 1, dfn[y]);
	return res;
}
void upchain(int x, int y) {
	while (head[x] != head[y]) {
		if (dep[head[x]] < dep[head[y]]) {
			swap(x, y);
		}
		up(1, 1, n, dfn[head[x]], dfn[x], -1);
		x = fa[head[x]];
	}
	if (dep[x] > dep[y]) {
		swap(x, y);
	}
	up(1, 1, n, dfn[x] + 1, dfn[y], -1);
}
int m;
vector<pair<int, int>>side;
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	cin >> n;
	for (int i = 1; i <= n * 4; i++) {
		tag[i] = 1;
	}
	for (int i = 1; i < n; i++) {
		int u, v, w;
		cin >> u >> v >> w;
		u++, v++;
		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);
	cin >> m;
	while (m--) {
		string op;
		int x, y;
		cin >> op >> x >> y;
		x++, y++;
		if (op == "C") {
			x -= 2, y--;
			int a = side[x].first, b = side[x].second;
			if (fa[a] == b) {
				swap(a, b);
			}
			up(1, 1, n, dfn[b], dfn[b], y);
		} else if (op == "N") {
			upchain(x, y);
		} else if (op == "SUM") {
			node ans = querychain(x, y);
			cout << ans.sum << "\n";
		} else if (op == "MAX") {
			node ans = querychain(x, y);
			cout << ans.ma << "\n";
		} else if (op == "MIN") {
			node ans = querychain(x, y);
			cout << ans.mi << "\n";
		}
	}
	return 0;
}

求助,84

回复

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

正在加载回复...