传送门
题解:LCT维护区间和,支持单点修改。
注意:!!!不要写modify(read(),read()),好像是因为传参的顺序不确定,反正我就是因为这玩意儿TLE了半个多小时。。。
#include<bits/stdc++.h>
using namespace std;
const int MAXN=3e4+5;
int n,q;
int fa[MAXN],ch[MAXN][2],rev[MAXN],sum[MAXN],val[MAXN];
inline int read() {
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x*f;
}
inline bool isroot(int rt) {
return ch[fa[rt]][0]!=rt&&ch[fa[rt]][1]!=rt;
}
inline void update(int rt) {
sum[rt]=val[rt];
if (ch[rt][0]) sum[rt]+=sum[ch[rt][0]];
if (ch[rt][1]) sum[rt]+=sum[ch[rt][1]];
}
inline void pushdown(int rt) {
if (!isroot(rt)) pushdown(fa[rt]);
if (rt&&rev[rt]) {
rev[rt]=0;
if (ch[rt][0]) rev[ch[rt][0]]^=1;
if (ch[rt][1]) rev[ch[rt][1]]^=1;
swap(ch[rt][0],ch[rt][1]);
}
}
inline void rotate(int x) {
int y=fa[x],which=(ch[y][1]==x),r=isroot(y);
ch[y][which]=ch[x][!which],ch[x][!which]=y,fa[ch[y][which]]=y,
fa[x]=fa[y],fa[y]=x;
if (!r)
ch[fa[x]][ch[fa[x]][1]==y]=x;
update(y),update(x);
}
inline void splay(int rt) {
pushdown(rt);
while (!isroot(rt)) {
int f=fa[rt],ff=fa[f];
if (isroot(f))
rotate(rt);
else if ((ch[ff][1]==f)==(ch[f][1]==rt))
rotate(f),rotate(rt);
else
rotate(rt),rotate(rt);
}
}
inline int access(int rt) {
int y=0;
while (rt) {
splay(rt),
ch[rt][1]=y,
update(rt),
y=rt,rt=fa[rt];
}
return y;
}
inline void makeroot(int rt) {
access(rt),
splay(rt),
rev[rt]^=1;
}
inline int find(int rt) {
access(rt);
splay(rt);
while (ch[rt][0]) rt=ch[rt][0];
return rt;
}
inline void modify(int x,int v) {
val[x]=v;
access(x);
splay(x);
}
inline void link(int u,int v) {
makeroot(u);
fa[u]=v;
}
inline int query(int u,int v) {
makeroot(u);
access(v);
splay(v);
return sum[v];
}
int main() {
// freopen("bzoj 2843.in","r",stdin);
n=read();
for (register int i=1;i<=n;++i)
sum[i]=val[i]=read(),fa[i]=ch[i][0]=ch[i][1]=rev[i]=0;
q=read();
for (register int i=0;i<q;++i) {
char ss[10];
scanf("%s",ss);
if (ss[0]=='b') {
int a=read(),b=read();
if (find(a)^find(b)) link(a,b),puts("yes");
else puts("no");
}
else if (ss[0]=='e') {
int a=read(),b=read();
if (find(a)==find(b)) printf("%d\n",query(a,b));
else puts("impossible");
}
else if (ss[0]=='p') {
int pos=read(),v=read();
modify(pos,v);
}
}
return 0;
}