社区讨论

LCT板子23分求调悬关

P3690【模板】动态树(LCT)参与者 1已保存回复 0

讨论操作

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

当前回复
0 条
当前快照
1 份
快照标识符
@lqrl1kqo
此快照首次捕获于
2023/12/30 12:48
2 年前
此快照最后确认于
2023/12/30 15:18
2 年前
查看原帖
rt, wa on #2 错了一个值,求调
我已经基本按题解默了哇…
CPP
#include<cstdio>
#include<cctype>
#include<algorithm>
using namespace std;

const int MAXN = 100005;

int n, m;

namespace Link_cut_Tree {
#define lc ch[u][0]
#define rc ch[u][1]
int val[MAXN], s[MAXN];
int fa[MAXN], ch[MAXN][2];
int tg[MAXN];
inline bool isroot(int u) {
	return ch[fa[u]][0] != u && ch[fa[u]][1] != u;
}
inline void push_up(int u) {
	s[u] = val[u] ^ s[lc] ^ s[rc];
}
inline void Reverse(int u) {
	swap(lc, rc);
	tg[u] ^= 1;
}
inline void push_down(int u) {
	if (!tg[u]) return;
	if (lc) Reverse(lc);
	if (rc) Reverse(rc);
	tg[u] = 0;
}
inline void Rotate(int u) {
	int fath = fa[u];
	int g_fa = fa[fath];
	int k = ch[fath][1] == u;
	fa[u] = g_fa;
	if (!isroot(fath))
		ch[g_fa][ch[g_fa][1] == fath] = u;
	if (ch[u][!k]) fa[ch[u][!k]] = fath;
	ch[fath][k] = ch[u][!k];
	ch[u][!k] = fath, fa[fath] = u;
	push_up(fath);
}
inline void pushll(int u) {
	if (!isroot(u)) pushll(fa[u]);
	push_down(u);
}
inline void Splay(int u) {
	pushll(u);
	int fath, g_fa;
	if (!isroot(u)) {
		fath = fa[u], g_fa = fa[fath];
		if (!isroot(fath))
			Rotate(((ch[fath][1] == u) ^ (ch[g_fa][1] == fath)) ? u : fath);
		Rotate(u);
	} 
	push_up(u);
}
inline void access(int u) {
	for (int son = 0; u; u = fa[son = u])
		Splay(u), rc = son, push_up(u);
}
inline void makeroot(int u) {
	access(u); Splay(u);
	Reverse(u);
}
inline int findroot(int u) {
	makeroot(u);
	while (lc) push_down(u), u = lc;
	Splay(u); return u;
}
inline void Split(int u, int v) {
	makeroot(u);
	access(v); Splay(v);
}
inline void Link(int u, int v) {
	makeroot(u);
	if (findroot(v) != u) fa[u] = v;
}
inline void cut(int u, int v) {
	makeroot(u);
	if (findroot(v) == u && fa[v] == u && !ch[v][0]) {
		fa[v] = ch[u][1] = 0;
		push_up(u);
	}
}
#undef lc
#undef rc
} 
using namespace Link_cut_Tree;

int main()
{
	scanf ("%d%d", &n, &m);
	for (int i = 1; i <= n; ++ i)
		scanf ("%d", val + i);
	int op, x, y;
	while (m --) {
		scanf ("%d%d%d", &op, &x, &y);
		switch(op) {
		case 0 : Split(x, y); printf ("%d\n", s[y]); break;
		case 1 : Link(x, y); break;
		case 2 : cut(x, y); break;
		case 3 : Splay(x); val[x] = y; push_up(x);
		}
	}
	return 0;
}

回复

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

正在加载回复...