裸LCT
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
struct Node
{
Node *lc,*rc,*f;
int data;
int sum;
bool Rev;
Node *pl;
inline bool h(){return f->lc==this||f->rc==this;}
inline bool l(){return f->lc==this;}
};
Node *empty;
inline void Begin(){empty=new Node;empty->data=0,empty->sum=0,empty->lc=empty->rc=empty;empty->Rev=0;}
inline Node *New_Node(){Node *tp=new Node;tp->data=0,tp->sum=0,tp->lc=empty;tp->rc=empty;tp->Rev=0;return tp;}
inline void updata(Node *a){a->sum=a->lc->sum+a->rc->sum+a->data;}
inline void Lc(Node *a)
{
Node *newf;
if(a->f->f==a->f)
newf=a;
else if(!a->f->h())
newf=a->f->f;
else if(a->f->l())
newf=a->f->f,a->f->f->lc=a;
else
newf=a->f->f,a->f->f->rc=a;
a->rc->f=a->f;
a->f->lc=a->rc;
a->rc=a->f;
a->f->f=a;
a->f=newf;
updata(a->rc);
updata(a);
}
inline void Rev(Node *a)
{Node *tp=a->lc;a->lc=a->rc;a->rc=tp;a->lc->Rev^=1,a->rc->Rev^=1,a->Rev^=1;}
inline void Rc(Node *a)
{
Node *newf;
if(a->f->f==a->f)
newf=a;
else if(!a->f->h())
newf=a->f->f;
else if(a->f->l())
newf=a->f->f,a->f->f->lc=a;
else
newf=a->f->f,a->f->f->rc=a;
a->lc->f=a->f;
a->f->rc=a->lc;
a->lc=a->f;
a->f->f=a;
a->f=newf;
updata(a->lc);
updata(a);
}
inline void Change(Node *a)
{a->l()?Lc(a):Rc(a);}
inline void Twice_Change(Node *a)
{
if(a->f->f->Rev)Rev(a->f->f);
if(a->f->Rev)Rev(a->f);
if(a->Rev)Rev(a);
a->l()==a->f->l()?Change(a->f):Change(a);Change(a);
}
inline void Once_Change(Node *a)
{
if(a->f->Rev)Rev(a->f);
if(a->Rev)Rev(a);
Change(a);
}
inline void Splay(Node *a)
{
while(a->f->h()&&a->h())Twice_Change(a);
while(a->h())Once_Change(a);
}
inline void Access(Node *a)
{
while(true){Splay(a);if(a->f==a)return;if(a->f->Rev)Rev(a->f);Splay(a->f);a->f->rc=a;}
}
inline void MakeRoot(Node *a)
{
Access(a);
a->lc->Rev^=1,a->lc=empty;
updata(a);
}
int F[100001];
int find(int x){return F[x]=(F[x]==x?x:find(F[x]));}
inline void Union(int x,int y){F[find(x)]=F[find(y)];}
Node S[100001];
char c;
inline void read(int &a)
{
a=0;do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
int main()
{
int n,m;
read(n);
Begin();
for(int i=1;i<=n;i++)
S[i].pl=S+i,F[i]=i,read(S[i].data),S[i].sum=S[i].data,S[i].f=&S[i],S[i].lc=empty,S[i].rc=empty;;
read(m);
int x,y;
for(int i=1;i<=m;i++)
{
do c=getchar();while(c!='b'&&c!='e'&&c!='p');
if(c=='b')
{
read(x),read(y);
if(find(x)==find(y))puts("no");
else puts("yes"),Union(x,y),MakeRoot(&S[x]),S[x].f=&S[y];
}
else if(c=='p')
{
read(x);
read(S[x].data),MakeRoot(&S[x]);
}
else if(c=='e')
{
read(x),read(y);
if(find(x)!=find(y))
puts("impossible");
else
{
MakeRoot(&S[x]);
Access(&S[y]);
printf("%d\n",S[y].lc->sum+S[y].data);
}
}
}
return 0;
}