LCT 第一题
LCT第一题,模板来自题解的博客,也是我学会LCT看的博客ORZ。
存一下好找。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 5e5 + 10;
typedef long long LL;
#define fa(x) T[x].f
#define ls(x) T[x].ch[0]
#define rs(x) T[x].ch[1]
int v[MAXN];
struct node {
int f, ch[2], s;
bool r;
} T[MAXN];
inline int read() {
char c = getchar();int x = 0,f = 1;
while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') { x = x * 10 + c - '0', c = getchar(); }
return x * f;
}
int ident(int x) {
return T[fa(x)].ch[0] == x ? 0 : 1;
}
int connect(int x, int fa, int how) {
T[x].f = fa;
T[fa].ch[how] = x;
}
inline bool isRoot(int x) { //若为splay中的根则返回1 否则返回0
return ls( fa(x) ) != x && rs( fa(x) ) != x;
//用到了两个性质
//1.若x与fa(x)之间的边是虚边,那么它的父亲的孩子中不会有他(不在同一个splay内)
//2. splay的根节点与其父亲之间的边是虚边
}
void push_up(int x) {
T[x].s = T[ls(x)].s ^ T[rs(x)].s ^ v[x]; //维护路径上的异或和
}
void push_down(int x) {
if(T[x].r) {
swap(ls(x),rs(x));
T[ls(x)].r ^= 1;
T[rs(x)].r ^= 1;
T[x].r = 0;
}
}
void rotate(int x) {
int Y = T[x].f, R = T[Y].f, Yson = ident(x), Rson = ident(Y);
int B = T[x].ch[Yson ^ 1];
T[x].f = R;
if(!isRoot(Y)) {
connect(x, R, Rson);
}
connect(B, Y, Yson);
connect(Y, x, Yson ^ 1);
push_up(Y); push_up(x);
}
int st[MAXN];
void splay(int x) {
int y = x, top = 0;
st[++top] = y;
while(!isRoot(y)) { st[++top] = y = fa(y); }
while(top) { push_down(st[top--]); }
for(int y = fa(x); !isRoot(x); rotate(x), y = fa(x)) {
if(!isRoot(y)) {
rotate( ident(x) == ident(y) ? x : y );
}
}
}
void access(int x) {
for(int y = 0; x; x = fa(y = x)) {
splay(x), rs(x) = y, push_up(x);
}
}
void make_root(int x) {
access(x);
splay(x);
T[x].r ^= 1;
push_down(x);
}
int find_root(int x) {
access(x); splay(x); push_down(x);
while(ls(x)) { push_down(x = ls(x)); }
return x;
}
void split(int x, int y) {
make_root(x); access(y); splay(y);
}
void link(int x, int y) {
make_root(x);
if(find_root(y) != x) {
fa(x) = y;
}
}
void cut(int x, int y) {
make_root(x);
if(find_root(y) == x && fa(x) == y && ls(y) == x && !rs(x)) {
fa(x) = T[y].ch[0] = 0;
push_up(y);
}
}
int main()
{
int N = read(), M = read();
for(int i = 1; i <= N; i++) v[i] = read();
for(int i = 1; i <= M; i++) {
int opt = read(), x = read(), y = read();
if(opt == 0) split(x, y), printf("%d
",T[y].s);
else if(opt == 1) link(x, y);
else if(opt == 2) cut(x, y);
else if(opt == 3) splay(x), v[x] = y;
}
return 0;
}