经检验,发现不知道哪里有两个点互相把父亲指向了对方。
#include<bits/stdc++.h>
#define lc t[x].c[0]
#define rc t[x].c[1]
using namespace std;
const int maxn=3e5+5;
struct tree
{
int c[2],v,dis,f;
}t[maxn];
int n,m,siz[maxn],tag[maxn],dlt,f[maxn];
char op[2];
multiset<int> s;
int getf(int x)
{
if(f[x]==x)return x;
return f[x]=getf(f[x]);
}
void pushtag(int x,int y)
{
t[x].v+=y;
if(lc)pushtag(lc,y);
if(rc)pushtag(rc,y);
}
void pushup(int x)
{
if(!x)return;
if(t[lc].dis<t[rc].dis)swap(lc,rc);
if(t[x].dis==t[rc].dis+1)return;
t[x].dis=t[rc].dis+1;
pushup(t[x].f);
}
int merge(int x,int y)
{
if(!x||!y)return x+y;
if(t[x].v<t[y].v)swap(x,y);
if(t[lc].dis<t[rc].dis)swap(lc,rc);
rc=merge(rc,y);
if(t[lc].dis<t[rc].dis)swap(lc,rc);
t[lc].f=t[rc].f=x;
pushup(x);
return x;
}
void insert(int x,int y)
{
lc=rc=t[x].f=0;
f[x]=f[y]=merge(x,y);
}
int main()
{
t[0].dis=-1;
int x,y;
scanf("%d",&n);
for(register int i=1;i<=n;i++)
{
scanf("%d",&t[i].v);
f[i]=i,siz[i]=1;
s.insert(t[i].v);
}
scanf("%d",&m);
for(register int i=1;i<=m;i++)
{
scanf("%s",op);
//puts("#");
switch(op[0])
{
case 'U':{
scanf("%d%d",&x,&y);
x=getf(x),y=getf(y);
if(x==y)break;
if(siz[x]>siz[y])swap(x,y);
pushtag(x,tag[x]-tag[y]);
f[x]=f[y]=merge(x,y);
if(f[x]==x)
{
puts("^");
s.erase(s.find(t[y].v+tag[y]));
tag[x]=tag[y],siz[x]+=siz[y],tag[y]=siz[y]=0;
}
else
{
puts("#");
s.erase(s.find(t[x].v+tag[y]));
siz[y]+=siz[x],tag[x]=siz[x]=0;
}
break;
}
case 'A':{
scanf("%d",&x);
switch(op[1])
{
case '1':{
scanf("%d",&y);
int z;
if(x==getf(x))
{
t[lc].f=t[rc].f=0;
z=merge(lc,rc);
s.erase(s.find(t[x].v+tag[x]));
t[x].v+=y;
insert(x,z);
s.insert(t[f[x]].v+tag[x]);
if(f[x]==z)tag[z]=tag[x],siz[z]=siz[x],tag[x]=siz[x]=0;
}
else
{
t[lc].f=t[rc].f=t[x].f;
t[t[x].f].c[x==t[t[x].f].c[1]]=merge(lc,rc);
t[x].v+=y;
z=getf(x);
insert(x,z);
if(f[x]==x)
{
puts("*");
s.erase(s.find(t[z].v+tag[z]));
s.insert(t[x].v+tag[z]);
tag[x]=tag[z],siz[x]=siz[z],tag[z]=siz[z]=0;
}
}
break;
}
case '2':{
scanf("%d",&y);
x=getf(x);
puts("$");
s.erase(s.find(t[x].v+tag[x]));
tag[x]+=y;
s.insert(t[x].v+tag[x]);
break;
}
case '3':{
dlt+=x;
break;
}
}
break;
}
case 'F':{
switch(op[1])
{
case '1':{
scanf("%d",&x);
printf("%d\n",t[x].v+tag[getf(x)]+dlt);
break;
}
case '2':{
scanf("%d",&x);
x=getf(x);
printf("%d\n",t[x].v+tag[x]+dlt);
break;
}
case '3':{
multiset<int>::iterator it=s.end();
puts("shik");
it--;
printf("%d\n",(*it)+dlt);
break;
}
}
}
}
// multiset<int>::iterator it=s.begin();
// while(it!=s.end())
// {
// cout<<*it<<' ';
// it++;
// }
// puts("");
}
return 0;
}