bzoj2333: [SCOI2011]棘手的操作
阿新 • • 發佈:2018-12-13
#include<bits/stdc++.h>
using namespace std;
const int N=300002;
int fa[N],l[N],r[N],x,y,w[N],add[N],d[N],n,i,m,rx,ry,v;
multiset<int>S;
char s[3];
#define gc getchar
inline int rd(){
int x=0,fl=1;char ch=gc();
for (;ch<48||ch>57;ch=gc())if(ch=='-')fl=-1;
for (;48 <=ch&&ch<=57;ch=gc())x=(x<<3)+(x<<1)+(ch^48);
return x*fl;
}
inline void wri(int a){if(a<0)a=-a,putchar('-');if(a>=10)wri(a/10);putchar(a%10|48);}
inline void wln(int a){wri(a),puts("");}
int find(int x){
while (fa[x]) x=fa[x];
return x;
}
void down(int x){
if (add[x]) w[l[x]]+=add[x],w[r[x]]+=add[x],add[l[x]]+=add[x],add[r[x]]+=add[x],add[x]=0;
}
void update(int x){
if (fa[x]) update(fa[x]);
down(x);
}
int merge(int x,int y){
if (!x || !y) return x+y;
down(x),down(y);
if (w[x]<w[y]) swap(x,y);
r[x]=merge(r[x],y);fa[r[x]]=x;
if (d[l[x]]<d[r[x]]) swap( l[x],r[x]);
d[x]=d[r[x]]+1;
return x;
}
int del(int x){
int f=fa[x],t=merge(l[x],r[x]);
fa[x]=l[x]=r[x]=0;
if (x==l[f]) l[f]=t;
else r[f]=t;
fa[t]=f;
return find(t);
}
void erase(int x){S.erase(S.find(x));}
int main(){
n=rd();
for (i=1;i<=n;i++) w[i]=rd(),S.insert(w[i]);
d[0]=-1;
for (m=rd();m--;){
scanf("%s",s);
if (s[0]=='U'){
x=rd(),y=rd();
rx=find(x),ry=find(y);
if (rx==ry) continue;
if (merge(rx,ry)==rx) erase(w[ry]);
else erase(w[rx]);
}
if (s[0]=='A'){
x=rd();
if (s[1]=='1') y=rd(),update(x),erase(w[find(x)]),w[x]+=y,S.insert(w[merge(x,del(x))]);
else if (s[1]=='2') y=rd(),rx=find(x),erase(w[rx]),S.insert(w[rx]+=y),add[rx]+=y;
else v+=x;
}
if (s[0]=='F'){
if (s[1]=='1') x=rd(),update(x),wln(w[x]+v);
else if (s[1]=='2') x=rd(),wln(w[find(x)]+v);
else wln(*(--S.end())+v);
}
}
}