bzoj 2049 [Sdoi2008]Cave 洞穴勘測 LCT
阿新 • • 發佈:2018-08-15
href git blog min pro rotate www rev bzoj
題面
題目傳送門
解法
LCT模板題
有些博客講得挺好的,轉一下
博客
這個挺詳細的
時間復雜度:\(O(m\ log\ n)\),盡管常數巨大
代碼
#include <bits/stdc++.h> #define N 20010 using namespace std; template <typename node> void chkmax(node &x, node y) {x = max(x, y);} template <typename node> void chkmin(node &x, node y) {x = min(x, y);} template <typename node> void read(node &x) { x = 0; int f = 1; char c = getchar(); while (!isdigit(c)) {if (c == ‘-‘) f = -1; c = getchar();} while (isdigit(c)) x = x * 10 + c - ‘0‘, c = getchar(); x *= f; } struct Node { int fa, rev, pathfa, child[2]; } t[N]; int n, m; int son(int x, int y) {return t[x].child[1] == y;} void rev(int x) {t[x].rev ^= 1;} void Clear() { for (int i = 1; i <= n; i++) t[i] = (Node) {0, false, 0, 0, 0}; } void pushdown(int k) { int x = t[k].rev; if (x) { swap(t[k].child[0], t[k].child[1]); rev(t[k].child[0]), rev(t[k].child[1]); t[k].rev = false; } } void Connect(int x, int y, int k) {t[x].child[k] = y, t[y].fa = x;} void Rotate(int x) { int y = t[x].fa, z = t[y].fa; pushdown(y); pushdown(x); int d = son(y, x); swap(t[x].pathfa, t[y].pathfa); Connect(z, x, son(z, y)); Connect(y, t[x].child[!d], d); Connect(x, y, !d); } void Splay(int x) { while (t[x].fa) { int y = t[x].fa, z = t[y].fa; if (z) { pushdown(z), pushdown(y); (son(z, y) ^ son(y, x)) ? Rotate(x) : Rotate(y); } Rotate(x); } } void expose(int x) { Splay(x); pushdown(x); int y = t[x].child[1]; t[y].fa = 0, t[y].pathfa = x; t[x].child[1] = 0; } void access(int x) { for (expose(x); t[x].pathfa; Splay(x)) { expose(t[x].pathfa); Connect(t[x].pathfa, x, 1); t[x].pathfa = 0; } } void evert(int x) {access(x), Splay(x), rev(x);} void link(int x, int y) {evert(y), t[y].pathfa = x;} void cut(int x, int y) { evert(x), access(y); Splay(y); pushdown(y); t[t[y].child[0]].fa = 0; t[y].child[0] = 0; } int Find(int x) { access(x); for (pushdown(x); t[x].child[0]; x = t[x].child[0], pushdown(x)); return x; } int main() { read(n), read(m); Clear(); while (m--) { char st[10]; scanf(" %s", st); int x, y; read(x), read(y); if (st[0] == ‘C‘) link(x, y); if (st[0] == ‘D‘) cut(x, y); if (st[0] == ‘Q‘) { int tx = Find(x), ty = Find(y); if (tx == ty) cout << "Yes\n"; else cout << "No\n"; } } return 0; }
bzoj 2049 [Sdoi2008]Cave 洞穴勘測 LCT