前言
之前学的LCT太差了。。
什么都不记得了
于是决定从今天开始,重新学习
学习笔记我就不学了,懒)
题解
这是一个模板题
一开始我的
isroot
i
s
r
o
o
t
写反了,调了好一会
然后还有要注意的就是
rotate
r
o
t
a
t
e
的时候要判断根
不要转到别人的子树里面去了
CODE:
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<iostream>
using namespace std;
const int N=300005;
int n,m;
struct qq
{
int fa,c;//父亲 子树的和
bool rev;
int son[2];
}tr[N];
int val[N];
void push_down (int now)
{
if (tr[now].rev==true)
{
int s1=tr[now].son[0],s2=tr[now].son[1];
swap(tr[now].son[0],tr[now].son[1]);
tr[s1].rev^=1;tr[s2].rev^=1;
tr[now].rev^=1;
}
}
bool is_root (int x)//这个点是不是所在splay的根
{
int fa=tr[x].fa;
//printf("%d %d\n",x,fa);
if (tr[fa].son[0]==x) return false;
if (tr[fa].son[1]==x) return false;
return true;
}
void pre (int x)
{
if (!is_root(x)) pre(tr[x].fa);
push_down(x);
}
void update (int now)
{
int s1=tr[now].son[0],s2=tr[now].son[1];
tr[now].c=(val[now]^tr[s1].c^tr[s2].c);
}
void rotate (int x)
{
int y=tr[x].fa,z=tr[y].fa,r,R;
int w=(tr[y].son[0]==x);
r=tr[x].son[w];R=y;
tr[R].son[1-w]=r;
if (r!=0) tr[r].fa=R;
r=x;R=z;
if (!is_root(y))
{
if (tr[R].son[0]==y) tr[R].son[0]=r;
else tr[R].son[1]=r;
}
tr[r].fa=R;
r=y;R=x;
tr[R].son[w]=r;
if (r!=0) tr[r].fa=R;
update(y);update(x);
}
void splay (int x)//使得x成为所在splay的根
{
pre(x);
//printf("TYB\n");
while (!is_root(x))
{
int y=tr[x].fa,z=tr[y].fa;
if (!is_root(y))
{
if ((tr[z].son[0]==y)==(tr[y].son[0]==x)) rotate(y);
else rotate(x);
}
rotate(x);
}
update(x);
}
void access (int x)//使得x变成偏爱儿子
{
int last=0;
while (x!=0)
{
//printf("%d %d\n",x,is_root(x));
splay(x);
tr[x].son[1]=last;
push_down(x);
last=x;
x=tr[x].fa;
}
}
void make_root (int x)//使得x变成原树的跟
{
access(x);splay(x);
tr[x].rev^=1;
}
void split (int x,int y)//分离这条路径 y当splay的根
{
make_root(x);
access(y);
splay(y);
}
int solve (int x,int y)
{
split(x,y);
return tr[y].c;
}
int find_root (int x)
{
access(x);//printf("YES\n");
splay(x);//printf("NO\n");
while (tr[x].son[0]!=0) x=tr[x].son[0];
return x;
}
void link (int x,int y)
{//printf("YES");
if (find_root(x)==find_root(y)) return ;
make_root(x);
tr[x].fa=y;
}
void cut (int x,int y)
{
if (find_root(x)!=find_root(y)) return ;
split(x,y);
tr[x].fa=tr[y].son[0]=0;
update(y);
}
int main()
{
scanf("%d%d",&n,&m);
for (int u=1;u<=n;u++)
{
scanf("%d",&val[u]);
tr[u].c=val[u];tr[u].rev=false;
}
for (int u=1;u<=m;u++)
{
int op,x,y;
scanf("%d%d%d",&op,&x,&y);
if (op==0) printf("%d\n",solve(x,y));
if (op==1) link(x,y);
if (op==2) cut(x,y);
if (op==3)
{
make_root(x);
tr[x].c^=val[x];
val[x]=y;
tr[x].c^=val[x];
}
}
return 0;
}