[BZOJ 3282] Tree 【LCT】
题目链接:BZOJ - 3282
题目分析
这道题是裸的LCT,包含 Link , Cut 和询问两点之间的路径信息。
写代码时出现的错误:Access(x) 的循环中应该切断的是原来的 Son[x][1] ,然而我写成了 Son[x][0] !
代码
#include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; inline void Read(int &Num) { char c = getchar(); bool Neg = false; while (c < '0' || c > '9') { if (c == '-') Neg = true; c = getchar(); } Num = c - '0'; c = getchar(); while (c >= '0' && c <= '9') { Num = Num * 10 + c - '0'; c = getchar(); } if (Neg) Num = -Num; } const int MaxN = 300000 + 5; int n, m; int A[MaxN], T[MaxN], Father[MaxN], Son[MaxN][2]; bool isRoot[MaxN], Rev[MaxN]; inline void Update(int x) { T[x] = T[Son[x][0]] ^ T[Son[x][1]] ^ A[x]; } inline void Reverse(int x) { Rev[x] = !Rev[x]; swap(Son[x][0], Son[x][1]); } inline void PushDown(int x) { if (!Rev[x]) return; Rev[x] = false; if (Son[x][0]) Reverse(Son[x][0]); if (Son[x][1]) Reverse(Son[x][1]); } void Rotate(int x) { int y = Father[x], f; PushDown(y); PushDown(x); if (x == Son[y][0]) f = 1; else f = 0; if (isRoot[y]) { isRoot[y] = false; isRoot[x] = true; } else { if (y == Son[Father[y]][0]) Son[Father[y]][0] = x; else Son[Father[y]][1] = x; } Father[x] = Father[y]; Son[y][f ^ 1] = Son[x][f]; if (Son[x][f]) Father[Son[x][f]] = y; Son[x][f] = y; Father[y] = x; Update(y); Update(x); } void Splay(int x) { int y; while (!isRoot[x]) { y = Father[x]; if (isRoot[y]) { Rotate(x); break; } if (y == Son[Father[y]][0]) { if (x == Son[y][0]) { Rotate(y); Rotate(x); } else { Rotate(x); Rotate(x); } } else { if (x == Son[y][1]) { Rotate(y); Rotate(x); } else { Rotate(x); Rotate(x); } } } } int Access(int x) { int y = 0; while (x != 0) { Splay(x); PushDown(x); if (Son[x][1]) isRoot[Son[x][1]] = true; Son[x][1] = y; if (y) isRoot[y] = false; Update(x); y = x; x = Father[x]; } return y; } void Make_Root(int x) { int t = Access(x); Reverse(t); } int Find_Root(int x) { int t = Access(x); while (Son[t][0] != 0) t = Son[t][0]; return t; } int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; ++i) { Read(A[i]); T[i] = A[i]; isRoot[i] = true; Father[i] = 0; } int f, x, y, t, fx, fy; for (int i = 1; i <= m; ++i) { Read(f); Read(x); Read(y); switch (f) { case 0 : Make_Root(x); t = Access(y); printf("%d\n", T[t]); break; case 1 : fx = Find_Root(x); fy = Find_Root(y); if (fx != fy) { Make_Root(x); Splay(x); Father[x] = y; } break; case 2 : Make_Root(x); Access(y); Splay(y); PushDown(y); if (Son[y][0] == x) { isRoot[Son[y][0]] = true; Father[Son[y][0]] = 0; Son[y][0] = 0; Update(y); } break; case 3 : Splay(x); A[x] = y; Update(x); break; } } return 0; }