76pts T3WA T4MLE 求助
查看原帖
76pts T3WA T4MLE 求助
109114
_l_l_楼主2021/6/16 21:35

如题。

#include <cstdio>
//#pragma GCC optimize(3)
const int MAXN = 200005;
int n;
inline void swap(int &x, int &y) {
	static int t = x;
	x = y;
	y = t;
}
namespace PUFS {
	int fa[MAXN * 40], dep[MAXN * 40], ls[MAXN * 40], rs[MAXN * 40];
	int cnt;
	void Build(int &rt, int l, int r) {//1
		rt = ++cnt;
		if (l == r) {
			fa[rt] = l, dep[rt] = 1;
			return;
		}
		int mid = l + r >> 1;
		Build(ls[rt], l, mid);
		Build(rs[rt], mid + 1, r);
	}
	void Change(int rt, int &newrt, int l, int r, int pos, int x) {//2
		newrt = ++cnt;
		ls[newrt] = ls[rt];
		rs[newrt] = rs[rt];
		if (l == r) {
			dep[newrt] = dep[rt];
			fa[newrt] = x;
			return;
		}
		int mid = l + r >> 1;
		if (pos <= mid) Change(ls[rt], ls[newrt], l, mid, pos, x);
		else Change(rs[rt], rs[newrt], mid + 1, r, pos, x);
	}
	void Add(int rt, int &newrt, int l, int r, int pos) {
		newrt = ++cnt;
		ls[newrt] = ls[rt];
		rs[newrt] = rs[rt];
		if (l == r) {
			dep[newrt] = dep[rt] + 1;
			fa[newrt] = fa[rt];
			return;
		}
		int mid = l + r >> 1;
		if (pos <= mid) Add(ls[rt], ls[newrt], l, mid, pos);
		else Add(rs[rt], rs[newrt], mid + 1, r, pos);
	}//3
	int Query(int rt, int l, int r, int pos) {//4
		if (l == r) {
			return rt;
		}
		int mid = l + r >> 1;
		if (pos <= mid) return Query(ls[rt], l, mid, pos);
		else return Query(rs[rt], mid + 1, r, pos);
	} 
	int Find(int rt, int a) {//5
		int f = Query(rt, 1, n, a);
		return fa[f] == a ? f : Find(rt, fa[f]);
	}
	void Merge(int rt, int &newrt, int u, int v) {
		u = Find(rt, u);
		v = Find(rt, v);
		if (fa[u] != fa[v]) {
			int tmprt;
			if (dep[u] > dep[v]) swap(u, v);
			Change(rt, tmprt, 1, n, fa[u], fa[v]);
			if (dep[u] == dep[v]) Add(tmprt, newrt, 1, n, fa[v]);
			else newrt = tmprt;
		}
		else {
			newrt = rt;
		}
	}
	bool Check(int rt, int &newrt, int u, int v) {
//		//\
//		Sans - 1 Attack 1 Defense \
//		The easiest enemy in the world \
//		Can only take 1 Damage
		newrt = rt;
		u = Find(rt, u);
		v = Find(rt, v);
		return fa[u] == fa[v];
	}
	void RollBack(int rt, int &newrt) {
		newrt = rt;
	}
}
int root[MAXN];
int main() {
//	freopen("1.in", "r", stdin);
//	freopen("1.out", "w", stdout);
	int m;
	scanf("%d %d", &n, &m);
	PUFS::Build(root[0], 1, n);
	int lastans = 0;
	for (int i = 1; i <= m; i++) {
		int a, b, c;
		scanf("%d %d", &a, &b);
//		b ^= lastans;
		if (a == 1) {
			scanf("%d", &c);
//			c ^= lastans;
			PUFS::Merge(root[i - 1], root[i], b, c);
		}
		if (a == 2) {
			PUFS::RollBack(root[b], root[i]);
		}
		if (a == 3) {
			scanf("%d", &c);
//			c ^= lastans;
			printf("%d\n", lastans = PUFS::Check(root[i - 1], root[i], b, c));
		}
	}
	return 0;
}
2021/6/16 21:35
加载中...