传送门
解析:
L C T LCT LCT裸题。
就常规的 L C T LCT LCT操作维护链上求和就行了啊。
真是少有的让我都能写出一句话题解的题目了。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
inline
int getint(){
re int num;
re char c;
while(!isdigit(c=gc()));num=c^48;
while(isdigit(c=gc()))num=(num<<1)+(num<<3)+(c^48);
return num;
}
inline
void outint(int a){
static char ch[13];
if(a==0)pc('0');
while(a)ch[++ch[0]]=a-a/10*10,a/=10;
while(ch[0])pc(ch[ch[0]--]^48);
}
inline char getalpha(){
re char c;
while(!isalpha(c=gc()));
return c;
}
cs int N=30004;
struct Link_Cut_Tree{
int fa[N];
int son[N][2];
int val[N],sum[N];
bool tag[N];
bool which(cs int &k){return son[fa[k]][1]==k;}
bool isroot(cs int &k){return son[fa[k]][0]!=k&&son[fa[k]][1]!=k;}
void pushdown(cs int &k){
if(tag[k]){
swap(son[k][0],son[k][1]);
if(son[k][0])tag[son[k][0]]^=1;
if(son[k][1])tag[son[k][1]]^=1;
tag[k]=0;
}
}
void pushup(cs int &k){
sum[k]=sum[son[k][0]]+sum[son[k][1]]+val[k];
}
void Rotate(cs int &now){
int Fa=fa[now],FA=fa[Fa];
bool pos=which(now);
if(!isroot(Fa))son[FA][which(Fa)]=now;
fa[Fa]=now;
fa[now]=FA;
son[Fa][pos]=son[now][!pos];
if(son[Fa][pos])fa[son[Fa][pos]]=Fa;
son[now][!pos]=Fa;
pushup(Fa);
pushup(now);
}
void Splay(cs int &now){
static int q[N],qn;
q[qn=1]=now;
for(int re Fa=now;!isroot(Fa);Fa=fa[Fa])q[++qn]=fa[Fa];
for(int re i=qn;i;--i)pushdown(q[i]);
for(int re Fa=fa[now];!isroot(now);Rotate(now),Fa=fa[now])
if(!isroot(Fa))Rotate(which(now)==which(Fa)?Fa:now);
}
void access(int now){
for(int re ch=0;now;ch=now,now=fa[now])
Splay(now),son[now][1]=ch,pushup(now);
}
void makeroot(cs int &now){
access(now);Splay(now);tag[now]^=1;
}
int findroot(int now){
access(now),Splay(now);
while(son[now][0])now=son[now][0];
return now;
}
bool connect(int u,int v){
makeroot(u);
return findroot(v)==u;
}
void link(int u,int v){
makeroot(u),fa[u]=v;
}
void update(int u,int v){
val[u]=v;
access(u),Splay(u);
}
int query(int u,int v){
makeroot(u),access(v);
Splay(v);
return sum[v];
}
}LCT;
int n,m;
signed main(){
n=getint();
for(int re i=1;i<=n;++i){
int x=getint();
LCT.update(i,x);
}
m=getint();
while(m--){
char op=getalpha();
int u=getint(),v=getint();
switch(op){
case 'e':{
if(!LCT.connect(u,v))puts("impossible");
else outint(LCT.query(u,v)),pc('\n');
break;
}
case 'b':{
if(LCT.connect(u,v))puts("no");
else puts("yes"),LCT.link(u,v);
break;
}
case 'p':{
LCT.update(u,v);
break;
}
}
}
return 0;
}