您的位置:首页 > 其它

【左偏树】【bzoj 2333】: [SCOI2011]棘手的操作

2015-03-01 21:19 501 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=2333

带lazy的左偏树,由于我不会写,所以借(chao)鉴(xi)了一下hzwer

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <set>
using namespace std;
#define rep(i,l,r) for(int i=(l),_=(r);i<=_;i++)
#define per(i,r,l) for(int i=(r),_=(l);i>=_;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define INE(i,u) for(int i=head[u];~i;i=e[i].next)
#define LL long long
inline const int read()
{int r=0,k=1;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;}
////////////////////////////////////////////////
const int inf=0x7fffffff;
const int N=300010;
int n;
struct node{int w,l,r,dis,fa,tag;}T
;
int all;
multiset<int>S;
////////////////////////////////////////////////
#define LS T[x].l
#define RS T[x].r
int find(int x){while(T[x].fa)x=T[x].fa;return x;}
void pushdown(int x)
{
if(T[x].tag)
{
int t=T[x].tag;
T[LS].tag+=t; T[LS].w+=t;
T[RS].tag+=t; T[RS].w+=t;
T[x].tag=0;
}
}
int merge(int x,int y)
{
if(!x||!y) return x+y;
if(T[x].w<T[y].w) swap(x,y);
pushdown(x);
RS=merge(RS,y); T[RS].fa=x;
if(T[LS].dis < T[RS].dis) swap(LS,RS);
if(RS == 0) T[x].dis=0;
else T[x].dis = T[RS].dis + 1;
return x;
}
void erasetag(int x)
{
static int q
;
for(;x;x=T[x].fa) q[++*q]=x;
for(;*q;--*q) pushdown(q[*q]);
}
int del(int x)
{
erasetag(x);
int f=T[x].fa,t=merge(LS,RS);
LS=RS=T[x].fa=0;
if(x == T[f].l) T[f].l=t;
else T[f].r=t;
T[t].fa=f;
return find(t);
}
void unio(int x,int y)
{
x=find(x); y=find(y);
if(x^y)
{
if(merge(x,y) == x) S.erase(S.find(T[y].w));
else S.erase(S.find(T[x].w));
}
}
void modify(int x,int w)
{
erasetag(x);
S.erase(S.find(T[find(x)].w));
T[x].w+=w;
S.insert(T[merge(x,del(x))].w);
}
void add(int x,int w)
{
x=find(x);
S.erase(S.find(T[x].w));
T[x].tag+=w; T[x].w+=w;
S.insert(T[x].w);
}
int getw(int x)
{
erasetag(x);
return T[x].w+all;
}
int getmax(int x)
{
return T[find(x)].w+all;
}
////////////////////////////////////////////////
void input()
{
rep(i,1,n=read()) T[i]=(node){read(),0,0,0,0,0};
rep(i,1,n) S.insert(T[i].w);
}
void solve()
{
char op[5];
rep(__,1,read())
{
scanf("%s",op);
if(op[0] == 'U')
{
int x=read(), y=read();
unio(x,y);
}
else if(op[0] == 'A')
{
if(op[1] == '1')
{
int x=read(), w=read();
modify(x,w);
}
else if(op[1] == '2')
{
int x=read(), w=read();
add(x,w);
}
else
{
all+=read();
}
}
else if(op[0] == 'F')
{
if(op[1] == '1')
{
int x=read();
printf("%d\n",getw(x));
}
else if(op[1] == '2')
{
int x=read();
printf("%d\n",getmax(x));
}
else
{
printf("%d\n",*S.rbegin() + all);
}
}
}
}
////////////////////////////////////////////////
int main()
{
freopen("_.in","r",stdin); freopen("_.out","w",stdout);
input(),solve();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: