样例求调
查看原帖
样例求调
637788
kimi0705楼主2024/10/19 11:00
#include <bits/stdc++.h>
using std::swap;
using std::vector;
const int N = 3e4 + 10;
const int Q = 3e5 + 10;
int n, q;
int arr[N];
char c[Q][10];
int in1[Q], in2[Q];
int ans[Q];
int father[N], son[N], top[N], siz[N], id[N], dep[N], rank[N], tot;
int sum[N], l[N], r[N];
vector<int> edge[N];
int fa[N];
int find(int x) {
	return fa[x] == x ? x : find(fa[x]);
}
bool merge(int x, int y) {
	int fx = find(x);
	int fy = find(y);
	if (fx == fy)
		return false;
	fa[fx] = fy;
	return true;
}
void dfs1(int x, int parent) {
	siz[x] = 1;
	dep[x] = dep[parent] + 1;
	father[x] = parent;
	for (int i : edge[x]) {
		if (i != parent) {
			dfs1(i, x);
			siz[x] += siz[i];
			if (siz[i] > siz[son[x]])
				son[x] = i;
		}
	}
}
void dfs2(int x, int parent) {
	top[x] = parent;
	id[x] = ++tot;
	rank[tot] = x;
	if (son[x])
		dfs2(son[x], parent);
	for (int i : edge[x]) {
		if (i != son[x])
			dfs2(i, i);
	}
}
void build(int o, int L, int R) {
	l[o] = L;
	r[o] = R;
	if (L == R) {
		sum[o] = arr[rank[L]];
		return;
	}
	int mid = (L + R) >> 1;
	build(o << 1, L, mid);
	build(o << 1 | 1, mid + 1, R);
	sum[o] = sum[o << 1] + sum[o << 1 | 1];
}
int query(int o, int L, int R) {
	if (L <= l[o] && r[o] <= R)
		return sum[o];
	int mid = (l[o] + r[o]) >> 1;
	int ans = 0;
	if (R <= mid)
		ans += query(o << 1, L, R);
	if (mid < R)
		ans += query(o << 1 | 1, L, R);
	return ans;
}
void update(int o, int id, int x) {
	if (l[o] == r[o]) {
		sum[o] = x;
		return;
	}
	int mid = (l[o] + r[o]) >> 1;
	if (id <= mid)
		update(o << 1, id, x);
	else
		update(o << 1 | 1, id, x);
	sum[o] = sum[o << 1] + sum[o << 1 | 1];
}
int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
		fa[i] = i;
	for (int i = 1; i <= n; i++)
		scanf("%d", &arr[i]);
	scanf("%d", &q);
	for (int i = 1; i <= q; i++)
		scanf("%s%d%d", c[i], &in1[i], &in2[i]);

	for (int i = 1; i <= q; i++)
		if (c[i][0] == 'y')
			if (merge(in1[i], in2[i])) {
				edge[in1[i]].push_back(in2[i]);
				edge[in2[i]].push_back(in1[i]);
			}
	dfs1(1, 1);
	dfs2(1, 1);
	build(1, 1, n);
	for (int i = 1; i <= n; i++)
		fa[i] = i;
	for (int i = 1; i <= q; i++) {
		if (c[i][0] == 'b') {
			if (merge(in1[i], in2[i]))
				puts("yes");
			else
				puts("no");
		} else if (c[i][0] == 'p') {
			update(1, id[in1[i]], in2[i]);
		} else {
			if (find(in1[i]) == find(in2[i])) {
				int res = 0;
				int L = in1[i], R = in2[i];
				while (top[L] != top[R]) {
					if (dep[top[L]] < dep[top[R]])
						swap(L, R);
					res += query(1, id[top[L]], id[L]);
					L = father[top[L]];
				}
				if (dep[top[L]] < dep[top[R]])
					swap(L, R);
				res += query(1, id[L], id[R]);
				printf("%d\n", res);
			} else {
				puts("impossible");
			}
		}
	}
}
2024/10/19 11:00
加载中...