题目链接
https://www.lydsy.com/JudgeOnline/problem.php?id=2843
题解
裸的不能再裸的LCT。
代码
#include <cstdio>
#include <algorithm>
int read()
{
int x=0,f=1;
char ch=getchar();
while((ch<'0')||(ch>'9'))
{
if(ch=='-')
{
f=-f;
}
ch=getchar();
}
while((ch>='0')&&(ch<='9'))
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
const int maxn=30000;
struct node
{
node *son[2],*fa;
int sum,val,rev;
};
int n,m,cnt;
char s[10];
node tnode[maxn+10];
node* newnode(int val)
{
node *x=&tnode[++cnt];
x->fa=x->son[0]=x->son[1]=NULL;
x->sum=x->val=val;
x->rev=0;
return x;
}
namespace lct
{
int pushdown(node *x)
{
if(x->rev)
{
std::swap(x->son[0],x->son[1]);
if(x->son[0]!=NULL)
{
x->son[0]->rev^=1;
}
if(x->son[1]!=NULL)
{
x->son[1]->rev^=1;
}
x->rev=0;
}
return 0;
}
int updata(node *x)
{
x->sum=x->val;
if(x->son[0]!=NULL)
{
x->sum+=x->son[0]->sum;
}
if(x->son[1]!=NULL)
{
x->sum+=x->son[1]->sum;
}
return 0;
}
int t(node *x)
{
return x==x->fa->son[1];
}
int isroot(node *x)
{
if(x->fa==NULL)
{
return 1;
}
if((x->fa->son[0]!=x)&&(x->fa->son[1]!=x))
{
return 1;
}
return 0;
}
int rotate(node *x)
{
node *f=x->fa;
pushdown(f);
pushdown(x);
int k=t(x);
x->fa=f->fa;
if(!isroot(f))
{
f->fa->son[t(f)]=x;
}
f->son[k]=x->son[!k];
if(x->son[!k]!=NULL)
{
x->son[!k]->fa=f;
}
f->fa=x;
x->son[!k]=f;
updata(f);
updata(x);
return 0;
}
int splayroot(node *x)
{
while(!isroot(x))
{
node *f=x->fa;
if(isroot(f))
{
rotate(x);
}
else if(t(f)==t(x))
{
rotate(f);
rotate(x);
}
else
{
rotate(x);
rotate(x);
}
}
return 0;
}
int access(node *x)
{
node *last=NULL;
while(x!=NULL)
{
splayroot(x);
pushdown(x);
x->son[1]=last;
updata(x);
last=x;
x=x->fa;
}
return 0;
}
int makeroot(node *x)
{
access(x);
splayroot(x);
x->rev^=1;
return 0;
}
int link(node *x,node *y)
{
makeroot(x);
node *f=y;
while(f->fa!=NULL)
{
f=f->fa;
}
if(f==x)
{
return -1;
}
makeroot(y);
y->fa=x;
return 0;
}
int getsum(node *x,node *y)
{
makeroot(x);
node *f=y;
while(f->fa!=NULL)
{
f=f->fa;
}
if(f!=x)
{
return -1;
}
access(y);
splayroot(y);
return y->sum;
}
int modify(node *x,int v)
{
splayroot(x);
x->val=v;
updata(x);
return 0;
}
}
int main()
{
n=read();
for(int i=1; i<=n; ++i)
{
int v=read();
newnode(v);
}
m=read();
while(m--)
{
scanf("%s",s);
int a=read(),b=read();
if(s[0]=='b')
{
puts(lct::link(&tnode[a],&tnode[b])?"no":"yes");
}
else if(s[0]=='p')
{
lct::modify(&tnode[a],b);
}
else
{
int ans=lct::getsum(&tnode[a],&tnode[b]);
if(ans==-1)
{
puts("impossible");
}
else
{
printf("%d\n",ans);
}
}
}
return 0;
}