二次联通门 : luogu P3690 【模板】Link Cut Tree
莫名RE第8个点。。。。如果有dalao帮忙查错的话万分感激
#include <cstdio> #include <iostream> #define Max 4000002 void read (int &now) { now = 0; bool temp = false; register char word = getchar (); while (word < '0' || word > '9') { if (word == '-') temp = false; word = getchar (); } while (word >= '0' && word <= '9') { now = now * 10 + word - '0'; word = getchar (); } if (temp) now = -now; } int N, M; struct S_D { S_D *child[2]; S_D *father; int key; int number; int Flandre; S_D (int __x) : number (__x) { child[0] = child[1] = NULL; father = NULL; key = __x; Flandre = 0; } inline void Updata () { /* this->key ^= this->number; if (this->child[0]) this->key ^= this->child[0]->key; if (this->child[1]) this->key ^= this->child[1]->key; */ if (this->child[0] != NULL && this->child[1] != NULL) this->key = this->child[0]->key ^ this->child[1]->key ^ this->number; else if (this->child[0] != NULL && this->child[1] == NULL) this->key = this->child[0]->key ^ this->number; else if (this->child[1] != NULL && this->child[0] == NULL) this->key = this->child[1]->key ^ this->number; else this->key = this->number; //this->key = this->child[0]->key ^ this->number ^ this->child[1]->key; return ; } inline void Down () { if (!this->Flandre) return ; std :: swap (this->child[0], this->child[1]); if (this->child[0]) this->child[0]->Flandre ^= 1; if (this->child[1]) this->child[1]->Flandre ^= 1; this->Flandre = 0; } inline int Get_Pos () { return this->father->child[1] == this; } inline int Is_Root () { return !(this->father) || (this->father->child[0] != this && this->father->child[1] != this); } }; S_D *data[Max]; S_D *node[Max]; class L_T { private : inline void Rotate (S_D *now) { int pos = now->Get_Pos () ^ 1; S_D *Father = now->father; Father->child[pos ^ 1] = now->child[pos]; if (now->child[pos]) now->child[pos]->father = Father; now->father = Father->father; if (!Father->Is_Root ()) now->father->child[Father->Get_Pos ()] = now; Father->father = now; now->child[pos] = Father; Father->Updata (); now->Updata (); } inline void Splay (S_D *now) { int pos = 0; for (S_D *Father = now; ; Father = Father->father) { data[++pos] = Father; if (Father->Is_Root ()) break; } for (; pos >= 1; -- pos) data[pos]->Down (); for (; !now->Is_Root (); Rotate (now)) if (!now->father->Is_Root ()) Rotate (now->Get_Pos () == now->father->Get_Pos () ? now->father : now); now->Updata (); } inline void Access (S_D *now) { for (S_D *Pre = NULL; now; Pre = now, now = now->father) { Splay (now); now->child[1] = Pre; now->Updata (); } } inline void Make_Root (S_D *now) { Access (now); Splay (now); now->Flandre ^= 1; } public : inline void Cut (S_D *x, S_D *y) { Make_Root (x); Access (y); Splay (y); x->father = y->child[0] = NULL; y->Updata (); } inline void Link (S_D *x, S_D *y) { Make_Root (x); x->father = y; } inline void Split (S_D *x, S_D *y) { Make_Root (x); Access (y); Splay (y); } inline bool Find (S_D *x, S_D *y) { while (x->child[0]) x = x->child[0]; while (y->child[0]) y = y->child[0]; return x == y; } inline int Query (int x, int y) { Split (node[x], node[y]); return node[y]->key; } inline void Change (int x, int y) { Access (node[x]); Splay (node[x]); node[x]->number = y; node[x]->Updata (); } }; L_T Make; int main (int argc, char *argv[]) { read (N); read (M); for (register int i = 0, x; i < N; i ++) { read (x); node[i] = new S_D (x); } int x, y, type; for (; M --; ) { read (type); read (x); read (y); if (type == 0) printf ("%d ", Make.Query (-- x, -- y)); else if (type == 1) { x --; y --; if (!Make.Find (node[x], node[y])) Make.Link (node[x], node[y]); } else if (type == 2) { x --; y --; if (Make.Find (node[x], node[y])) Make.Cut (node[x], node[y]); } else Make.Change (-- x, y); } return 0; }