BZOJ1295 [SCOI2009]最长距离
20150228 bc31

BZOJ1455 罗马游戏

laekov posted @ 2015年2月27日 14:52 in 未分类 with tags bzoj ds , 566 阅读

左偏树+并查集的一眼题嘛。然后合并的时候搞忘了如果两个人已经在同一个团里要跳过,于是左偏树自交去了。

 

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

#define szof(p) ((p)?(p->sz):0)
struct node {
	int sz, vl, id;
	node *ls, *rs;
	node() {}
	node(int v, int i) {
		vl = v;
		id = i;
		sz = 1;
		ls = rs = 0;
	}
	inline void update() {
		if (szof(ls) < szof(rs))
			swap(ls, rs);
	}
};
node *merge(node* p, node* q) {
	if (!p)
		return q;
	else if (!q)
		return p;
	else if (p-> vl < q-> vl) {
		p-> rs = merge(p-> rs, q);
		p-> update();
		return p;
	}
	else {
		q-> rs = merge(q-> rs, p);
		q-> update();
		return q;
	}
}
node *pop(node* p) {
	if (p)
		return merge(p-> ls, p-> rs);
	else
		return 0;
}

const int maxn = 1000009;

int n, m, r[maxn];
bool al[maxn];
node nlst[maxn], *rt[maxn];

int getRoot(int x) {
	register int p, q;
	for (p = r[x]; p ^ r[p]; p = r[p]);
	for (; x ^ p; q = r[x], r[x] = p, x = q);
	return x;
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
#endif

	scanf("%d", &n);
	for (int i = 1; i <= n; ++ i) {
		int w;
		scanf("%d", &w);
		nlst[i] = node(w, i);
		rt[i] = &nlst[i];
		al[i] = 1;
		r[i] = i;
	}
	scanf("%d", &m);
	while (m --) {
		char opt[3];
		int a, b;
		scanf("%s", opt);
		if (opt[0] == 'M') {
			scanf("%d%d", &a, &b);
			if (al[a] && al[b]) {
				a = getRoot(a);
				b = getRoot(b);
				if (a == b)
					continue;
				r[a] = b;
				rt[b] = merge(rt[b], rt[a]);
			}
		}
		else if (opt[0] == 'K') {
			scanf("%d", &a);
			if (!al[a])
				puts("0");
			else {
				a = getRoot(a);
				printf("%d\n", rt[a]-> vl);
				al[rt[a]-> id] = 0;
				rt[a] = pop(rt[a]);
			}
		}
	}
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter