最近C语言刚学指针,想要练练手
于是写了个指针版的LCT
代码比较好理解,和非指针版的LCT差不多
但是感觉还是有点慢。。。
代码:(【模板】动态树(Link-Cut-Tree))
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int gi()
{
char c;int num=0,flg=1;
while((c=getchar())<'0'||c>'9')if(c=='-')flg=-1;
while(c>='0'&c<='9'){num=num*10+c-48;c=getchar();}
return num*flg;
}
#define N 100005
#define X (*x)
#define Y (*y)
#define lc X.ch[0]
#define rc X.ch[1]
struct LCT{
int sum,num;
bool rev;
LCT *ch[2];
LCT *fa;
}a[N];
const LCT * const nu=&a[0];
void pushup(LCT* x)
{
X.sum=(*lc).sum^(*rc).sum^X.num;
}
void pushdown(LCT* x)
{
if(X.rev){
swap(lc,rc);
if(lc!=nu)(*lc).rev^=1;
if(rc!=nu)(*rc).rev^=1;
X.rev=0;
}
}
bool pdc(LCT* x){return (*X.fa).ch[1]==x;}
bool pdr(LCT* x){return (*X.fa).ch[0]!=x&&(*X.fa).ch[1]!=x;}
void rot(LCT* x)
{
LCT *y=X.fa,*z=Y.fa;
bool flg=pdc(x);
if(!pdr(y))(*z).ch[pdc(y)]=x;
if((Y.ch[flg]=X.ch[flg^1])!=nu)
(*Y.ch[flg]).fa=y;
X.ch[flg^1]=y;
Y.fa=x;X.fa=z;
pushup(y);pushup(x);
}
void pdp(LCT* x)
{
if(!pdr(x))pdp(X.fa);
pushdown(x);
}
void splay(LCT* x)
{
pdp(x);
for(;!pdr(x);rot(x))
if(!pdr(X.fa))
rot(pdc(x)==pdc(X.fa)?X.fa:x);
}
LCT* Access(LCT* x)
{
LCT* p=&a[0];
for(;x!=nu;p=x,x=X.fa){
splay(x);
X.ch[1]=p;
pushup(x);
}
return p;
}
LCT* LCA(LCT* x,LCT* y)
{
Access(x);
return Access(y);
}
void beroot(LCT* x)
{
Access(x);
splay(x);
X.rev^=1;
}
LCT* findroot(LCT* x)
{
Access(x);
splay(x);
while(X.ch[0]!=nu)
x=X.ch[0];
return x;
}
void link(LCT* x,LCT* y)
{
beroot(x);
X.fa=y;
}
void cut(LCT* x,LCT* y)
{
beroot(x);
Access(y);
splay(y);
if(x==Y.ch[0]){
Y.ch[0]=X.fa=&a[0];
pushup(y);
}
}
int getsum(LCT* x,LCT* y)
{
beroot(x);
Access(y);
splay(y);
return Y.sum;
}
int main()
{
int n,m,i,op,nx,ny;
n=gi();m=gi();
for(i=0;i<=n;i++){
if(i>0)a[i].num=a[i].sum=gi();
a[i].ch[0]=a[i].ch[1]=a[i].fa=&a[0];
}
for(i=1;i<=m;i++){
op=gi();nx=gi();ny=gi();
if(op<=2){
LCT *x=&a[nx],*y=&a[ny];
if(op==0)
printf("%d\n",getsum(x,y));
else if(op==1){
LCT *fx=findroot(x),*fy=findroot(y);
if(fx!=fy)link(x,y);
}
else if(op==2)cut(x,y);
}
else{
LCT *x=&a[nx];
beroot(x);
X.num=ny;
pushup(x);
}
}
}