题解:
对于第一个操作我们可以用并查集来搞,
然后离线+树链剖分+树状数组,
感觉不是很难想,后来看了看题解发现全都用lct,蒟蒻lct太弱QWQ,只好乱搞了。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
const int M=30010;
int n,m;
int v[M],f[M];
char s[N],s1[20];
int x[N],y[N];
struct node{
int x,y,next;
}sa[N*2];int len=1,first[M];
bool tf[M];
int bit[N];
int lowbit(int x)
{
return x&-x;
}
void add(int x,int y)
{
while(x<=n)
{
bit[x]+=y;
x+=lowbit(x);
}
}
int getsum(int x)
{
int sum=0;
while(x>=1)
{
sum+=bit[x];
x-=lowbit(x);
}
return sum;
}
int findfa(int x){
int a=x,c;
while(x!=f[x])x=f[x];
while(x!=(c=f[a]))f[a]=x,a=c;
return x;
}
void ins(int x,int y)
{
len++;
sa[len].x=x;
sa[len].y=y;
sa[len].next=first[x];
first[x]=len;
}
int dep[M],son[M],size[M],fa[M];
void dfs1(int x,int pa)
{
size[x]=1;
fa[x]=pa;
for(int i=first[x];i!=-1;i=sa[i].next)
{
int y=sa[i].y;
if(y!=pa)
{
dep[y]=dep[x]+1;
dfs1(y,x);
size[x]+=size[y];
if(size[son[x]]<size[y]) son[x]=y;
}
}
}
int top[M],id[M],idn=0;
void dfs2(int x,int tp)
{
//printf("%d %d\n",x,tp);
//system("pause\n");
top[x]=tp;
id[x]=++idn;
add(id[x],v[x]);
if(son[x]) dfs2(son[x],tp);
for(int i=first[x];i!=-1;i=sa[i].next)
{
int y=sa[i].y;
if(y!=fa[x]&&y!=son[x])
{
dfs2(y,y);
}
}
}
int solve(int x,int y)
{
/*int tx=top[x],ty=top[y],s=0;
while(tx!=ty)
{
if(dep[x]>dep[y]) swap(x,y),swap(tx,ty);
s+=getsum(id[y])-getsum(id[ty]-1);
y=fa[ty];ty=top[y];
}
if(dep[x]>dep[y]) swap(x,y);
s+=getsum(id[y])-getsum(id[x]-1);
return s;*/
int a=top[x],b=top[y],c,s=0;
while(a!=b){
if(dep[a]<dep[b]){
s+=getsum(id[y])-getsum(id[b]-1);
y=fa[b];b=top[y];
}else{
s+=getsum(id[x])-getsum(id[a]-1);
x=fa[a];a=top[x];
}
}
if(dep[x]<dep[y])s+=getsum(id[y])-getsum(id[x]-1);
else s+=getsum(id[x])-getsum(id[y]-1);
return s;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)f[i]=i;
for(int i=1;i<=n;i++) scanf("%d",&v[i]);
memset(first,-1,sizeof(first));
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%s",s1);
scanf("%d%d",&x[i],&y[i]);
s[i]=s1[0];
if(s1[0]=='b')
{
int tx=findfa(x[i]),ty=findfa(y[i]);
if(tx!=ty)
{
f[tx]=ty;
ins(x[i],y[i]);ins(y[i],x[i]);
}
}
}
memset(bit,0,sizeof(bit));
// for(int i=1;i<=n;i++) printf("%d\n",fa[i]);
for(int i=1;i<=n;i++)
if(!tf[findfa(i)])
{
tf[findfa(i)]=true;
dfs1(i,0);dfs2(i,i);//printf("@\n");printf("!");
}
// printf("!");
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=m;i++)
{
if(s[i]=='b')
{
int tx=findfa(x[i]),ty=findfa(y[i]);
if(tx!=ty) f[tx]=ty,printf("yes\n");
else printf("no\n");
}
else if(s[i]=='p')
{
int yu=y[i]-v[x[i]];
v[x[i]]+=yu;
add(id[x[i]],yu);
}
else
{
int tx=findfa(x[i]),ty=findfa(y[i]);
if(tx!=ty)printf("impossible\n");
else printf("%d\n",solve(x[i],y[i]));
}
}
}