rt。这里的太慢指的是板子题用时几乎是同学的 1.5 倍。求助是我哪里写假了还是别的原因。(注:我的 splay 水平仅限于知道原理并且能写出来 LCT 用的板子,因此如果是 splay 的原因您直接告诉我怎么改就好)
本身写啥常数都大,万一考场上写了被卡常遗恨千年,因此来求助。
代码如下。
#include<algorithm>
#include<cstdio>
#include<vector>
const int maxn=1e5+5;
struct node{
bool turn;
int fa,ch[2],val;
#define l ch[0]
#define r ch[1]
}tree[maxn];
int v[maxn];
void update(int i){
tree[i].val=tree[tree[i].l].val^tree[tree[i].r].val^v[i];
return;
}
void con(int x,int f,int tp){
tree[f].ch[tp]=x,tree[x].fa=f;
return;
}
bool isroot(int x){return tree[tree[x].fa].l!=x&&tree[tree[x].fa].r!=x;}
int ident(int x){return tree[tree[x].fa].l==x?0:1;}
void pushdown(int x){
if(tree[x].turn){
std::swap(tree[x].l,tree[x].r);
tree[tree[x].l].turn^=1,tree[tree[x].r].turn^=1;
tree[x].turn=false;
}
return;
}
void rotate(int x){
int f=tree[x].fa,ff=tree[f].fa,fson=ident(x),ffson=ident(f),d=tree[x].ch[fson^1];
tree[x].fa=ff;
if(!isroot(f))con(x,ff,ffson);
con(d,f,fson),con(f,x,fson^1);
update(f),update(x);
return;
}
int stk[maxn],scnt;
void splay(int x){
int y=x;
stk[scnt=1]=y;
while(!isroot(y))y=tree[y].fa,stk[++scnt]=y;
while(scnt)pushdown(stk[scnt--]);
for(int y=tree[x].fa;!isroot(x);y=tree[x].fa){
if(!isroot(y))rotate(ident(x)==ident(y)?y:x);
rotate(x);
}
return;
}
void access(int x){
for(int y=0;x;x=tree[y].fa)splay(x),tree[x].r=y,update(y=x);
return;
}
void maker(int x){
access(x),splay(x),tree[x].turn^=true,pushdown(x);
return;
}
void road(int x,int y){
maker(x),access(y),splay(y);
return;
}
int findr(int x){
access(x),splay(x);
while(tree[x].l)x=tree[x].l,pushdown(x);
return x;
}
void link(int x,int y){
road(x,y);
if(findr(y)!=x)tree[x].fa=y;
return;
}
void cut(int x,int y){
road(x,y);
if(tree[y].l==x&&!tree[x].r)tree[y].l=tree[x].fa=0,update(y);
return;
}
#undef l
#undef r
int n,m;
signed main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",v+i);
for(int i=1;i<=m;i++){
int opt,x,y;
scanf("%d%d%d",&opt,&x,&y);
if(opt==0)road(x,y),printf("%d\n",tree[y].val);
else if(opt==1)link(x,y);
else if(opt==2)cut(x,y);
else splay(x),v[x]=y;
}
return 0;
}