刚学 OI ,求助这道题。
查看原帖
刚学 OI ,求助这道题。
486187
vvautedSN第一魔怔人楼主2021/9/4 13:50
#include <stdio.h>
#include <string>
#include <iostream>
#define Maxn 300005
using namespace std;

int n, m, a[Maxn], root[Maxn], alt, cnt, fa[Maxn], tree[Maxn << 2], maxx, tag[Maxn << 2], L[Maxn], R[Maxn], tot;

int max(int a,int b) {
	return a > b ? a : b; 
}

int find(int x) {
	return root[x] == x ? x : root[x] = find(root[x]);
}

void push_up(int x) {
	tree[x] = max(tree[L[x]] + tag[L[x]] , tree[R[x]] + tag[R[x]]);
}

void merge(int x, int y) {
	L[++ tot] = find(x), R[tot] = find(y);
	root[tot] = fa[R[tot]] = fa[tot] = fa[L[tot]] = root[R[tot]] = root[L[tot]] = tot;
	push_up(tot);
}

int query(int x) {
	return fa[x] == x ? tag[x] : tag[x] + query(fa[x]);
} 

void add(int x, int k) {
	tag[find(x)] += k; 
	if(tree[find(maxx)] + tag[find(maxx)] < tree[find(x)] + tag[find(x)] ) maxx = find(x);
}

void upd(int x) {
	if(root[x] == x){
		if(tree[x] + tag[x] > tree[find(maxx)] + tag[find(maxx)]) maxx = x;
		else return;
	}
	else if(tree[x] + tag[x] > tree[fa[x]]) {
		push_up(fa[x]), upd(fa[x]);
	}
}
int main() {
	scanf("%d", &n);
	for(int i = 1; i <= n; ++ i) {
		scanf("%d", &a[i]);
		tree[i] = a[i];
		root[i] = fa[i] = i;
		if(a[i] > a[maxx]) maxx = i;
	}
	tot = n;
	scanf("%d", &m);
	string s;
	int x, y, i;
	for(i = 1; i <= m; ++ i) {
		cin >> s;
		if(s[0] == 'U') {
			scanf("%d%d", &x, &y);
			if(find(x) != find(y)) merge(x, y);
		} else if (s[0] == 'A') {
			if(s[1] == '1') {
				scanf("%d%d", &x, &y);
				a[x] += y;
				tree[x] += y;
				upd(x);
			} else if(s[1] == '2') {
				scanf("%d%d", &x, &y);
				add(x, y);
			} else if(s[1] == '3') {
				scanf("%d", &x);
				alt += x;
			}
		} else {
			if(s[1] == '1') {
				scanf("%d",  &x);
				printf("%d\n", tree[x] + alt + query(x));
			} else if(s[1] == '2') {
				scanf("%d", &x);
				printf("%d\n",  tree[find(x)] + alt + tag[find(x)]);
			} else {
				printf("%d\n", tree[find(maxx)] + tag[find(maxx)] + alt);
			}
		}
	}
} 

思路大概就是 合并联通块时把两个联通块的 root 合并到一个新的节点 作为 root。 每次联通块加都在 root 打上 tag,算单点的时候统计下 到 root 路径上的 tag 和 aia_i 加起来即可,不知道为什么 WA 了 9个点

2021/9/4 13:50
加载中...