您的位置:首页 > 其它

BZOJ 2333 左偏树 (写得我人生都崩溃了...)

2017-03-28 23:47 120 查看

思路:

高一神犇 竟然 问我这道题   我光荣地  看着题解(划掉)  写了一下午 QaQ

multiset不能erase(一个值)   这样就把等于这个值 的数都erase掉了  (woc我一开始不知道啊啊啊 )

注意细节...

//By SiriusRen
#include <set>
#include <cstdio>
using namespace std;
const int N=300050;
int n,q,all,xx,yy;
char op[3];
struct Tree{int w,l,r,fa,dis,lazy;}tr
;
int find(int x){while(tr[x].fa)x=tr[x].fa;return x;}
void push_down(int x){
if(tr[x].l)tr[tr[x].l].w+=tr[x].lazy,tr[tr[x].l].lazy+=tr[x].lazy;
if(tr[x].r)tr[tr[x].r].w+=tr[x].lazy,tr[tr[x].r].lazy+=tr[x].lazy;
tr[x].lazy=0;
}
int merge(int x,int y){
if(x*y==0)return x+y;
if(tr[x].w<tr[y].w)swap(x,y);
push_down(x);
tr[x].r=merge(tr[x].r,y);
tr[tr[x].r].fa=x;
if(tr[tr[x].l].dis<tr[tr[x].r].dis)swap(tr[x].l,tr[x].r);
tr[x].dis=tr[tr[x].r].dis+1;
return x;
}
int del(int x){
int F=tr[x].fa,t;
push_down(x);tr[t=merge(tr[x].l,tr[x].r)].fa=F;
tr[x].l=tr[x].r=tr[x].fa=tr[x].dis=0;
if(tr[F].l==x)tr[F].l=t;
else tr[F].r=t;
while(tr[t].fa)t=tr[t].fa;
return find(t);
}
void dfs(int x){
if(tr[x].fa)dfs(tr[x].fa);
push_down(x);
}
multiset<int>s;multiset<int>::iterator it;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&tr[i].w),s.insert(tr[i].w);
scanf("%d",&q);
for(int I=1;I<=q;I++){
scanf("%s",op);
if(op[0]=='A'){
if(op[1]=='1'){
scanf("%d%d",&xx,&yy);
dfs(xx);
s.erase(s.find(tr[find(xx)].w));
tr[xx].w+=yy;
s.insert(tr[merge(del(xx),xx)].w);
}
else if(op[1]=='2'){
scanf("%d%d",&xx,&yy);
int fx=find(xx);
s.erase(s.find(tr[fx].w));
tr[fx].w+=yy,tr[fx].lazy+=yy;
s.insert(tr[fx].w);
}
else if(op[1]=='3')scanf("%d",&xx),all+=xx;
}
else if(op[0]=='F'){
if(op[1]=='1'){
scanf("%d",&xx);dfs(xx);
printf("%d\n",tr[xx].w+all);
}
else if(op[1]=='2'){
scanf("%d",&xx);
printf("%d\n",tr[find(xx)].w+all);
}
else if(op[1]=='3'){
it=s.end();it--;
printf("%d\n",(*it)+all);
}
}
else{
scanf("%d%d",&xx,&yy);
int fx=find(xx),fy=find(yy);
if(fx!=fy){
if(merge(fx,fy)==fy)s.erase(s.find(tr[fx].w));
else s.erase(s.find(tr[fy].w));
}
}
}
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: