题目链接

还是80分,不是很懂。

/*
七个操作(用左偏树)(t2表示第二棵子树):
1.合并:直接合并(需要将一个t2中原有的根节点删掉)
2.单点加:把这个点从它的堆里删了,加了再插入回去(有负数)(它可能成为这一个堆的根,所以也要从t2中删除再插入)
3.整个连通块加:根节点打标记(从t2中删除,改数,再插入到t2)
4.所有节点加:全局标记
5.输出某个点的值:向上加上所有父节点的值,输出
6.输出某个点所在连通块的最大值:找到根,输出
7.输出所有节点的最大值:将所有堆的根节点取出,再维护第二棵子树 (1)
在要改动子节点要下传父节点标记,像线段树一样
(2)
左偏树的删除:左偏树不具有平衡树的性质,所以做不到删除权值为某个值的点,但是可以删除指定下标的点
先合并要删除的点x的左右子树为s,再将左右合并后的子树与fa[x]合并
合并后新树距离可能会改变,因此要更新fa[x]的距离
如果dis[s]+1<dis[fa],则dis[fa]的距离要改小,如果s是fa的左子树,还要交换左右子树
因为dis[fa]的距离改了所以要继续往上
如果dis[s]+1>dis[fa],如果s是左子树就可以结束;如果是右子树,若dis[s]<dis[left],则更新fa的距离,否则还要再交换一次子树,再向上更新
(3)
单点加/减(主要是减)有可能在根,这会导致树根发生改变
对于第二棵左偏树,需要维护树根位置以解决操作7
(4)
注意第二棵树开始时的建树,将所有原节点合并
(5)
合并两棵子树需将那棵根不是合并后的根节点的子树从第二棵中删掉
(6)
第二棵树存的是每堆的根节点,所以要对对应堆的根节点进行操作
(7)
将一个点取出重新插入时记得Init
*/
#include<cstdio>
#include<cctype>
#include<algorithm>
//#define gc() (SS==TT &&(TT=(SS=IN)+fread(IN,1,1<<22,stdin),SS==TT)?EOF:*SS++)
#define gc() getchar()
const int N=3e5+5; int n,TAG,q[N],root;
//char IN[1<<22],*SS=IN,*TT=IN; inline int read()
{
int now=0,f=1;register char c=gc();
for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now*f;
}
struct Leftist_Tree
{
int val[N],fa[N],son[N][2],tag[N],dis[N];
void Init(int p){fa[p]=son[p][0]=son[p][1]=0;}
inline void PushDown(int x)
{
if(son[x][0]) val[son[x][0]]+=tag[x],tag[son[x][0]]+=tag[x];
if(son[x][1]) val[son[x][1]]+=tag[x],tag[son[x][1]]+=tag[x];
tag[x]=0;
}
int Getf(int p)
{
while(fa[p]) p=fa[p];
return p;
}
int Sum(int p)//到根节点路径的标记和
{
int res=0;
while(p=fa[p]) res+=tag[p];
return res;
}
int Merge(int A,int B)
{
if(!A||!B) return A+B;
if(val[A]<val[B]) std::swap(A,B);
if(tag[A]) PushDown(A);
son[A][1]=Merge(son[A][1],B);
fa[son[A][1]]=A;
if(dis[son[A][1]]>dis[son[A][0]]) std::swap(son[A][0],son[A][1]);
dis[A]=dis[son[A][1]]+1;
return A;
}
int Delete(int x)
{
if(tag[x]) PushDown(x);
int f=fa[x],s=Merge(son[x][0],son[x][1]);
fa[s]=f;
if(f) son[f][son[f][1]==x]=s;
while(f)
{
if(dis[son[f][0]]<dis[son[f][1]]) std::swap(son[f][0],son[f][1]);
if(dis[son[f][1]]+1==dis[f]) return root;//根节点没有改变(距离并未发生改变),直接return原来的根
dis[f]=dis[son[f][1]]+1;
// fa[son[f][1]]=f;
s=f, f=fa[f];
}
return s;//新的根节点 这个不要随便设,初始就是s,因为s可能就是根节点(f=0)
}
int Add_Point(int x,int v)
{
int rt=Getf(x);
if(rt==x)
if(!(son[x][0]+son[x][1])||v>=0){val[x]+=v;return x;}
else if(son[x][0]) rt=son[x][0];
else rt=son[x][1];
Delete(x);
val[x]+=v+Sum(x);
Init(x);
return Merge(Getf(rt),x);//要合并Getf(rt)!删除后已经更新树了
}
int Build()
{
int h=0,t=0,x,y;
for(int i=1;i<=n;++i) q[t++]=i;
while(h<t-1)
{
x=q[h++],y=q[h++];
q[t++]=Merge(x,y);
}
return q[t-1];//返回第二棵子树的根节点
}
}t1,t2; int main()
{
#ifndef ONLINE_JUDGE
freopen("3273.in","r",stdin);
#endif t1.dis[0]=t2.dis[0]=-1;
n=read();
for(int i=1;i<=n;++i) t1.val[i]=t2.val[i]=read();
root=t2.Build();
int q=read(),x,y,rx,ry,v,tmp;
char s[5];
while(q--)
{
scanf("%s",s);
if(s[0]=='U')
{
x=read(),y=read(),rx=t1.Getf(x),ry=t1.Getf(y);
if(rx==ry) continue;
tmp=t1.Merge(rx,ry);
if(tmp==rx) root=t2.Delete(ry);
else root=t2.Delete(rx);
}
else if(s[0]=='A')
if(s[1]=='1')
{
x=read(),v=read();
root=t2.Delete(t1.Getf(x));
ry=t1.Add_Point(x,v);//第一棵子树更新后x所在堆的根节点
t2.val[ry]=t1.val[ry];
t2.Init(ry);
root=t2.Merge(root,ry);
}
else if(s[1]=='2')
{
x=read(),v=read();
root=t2.Delete((rx=t1.Getf(x)));
t1.val[rx]+=v, t1.tag[rx]+=v;
t2.val[rx]=t1.val[rx];
t2.Init(rx);
root=t2.Merge(root,rx);
}
else
v=read(), TAG+=v;
else if(s[0]=='F')
if(s[1]=='1') x=read(), printf("%d\n",t1.val[x]+t1.Sum(x)+TAG);
else if(s[1]=='2') x=read(), printf("%d\n",t1.val[t1.Getf(x)]+TAG);
else printf("%d\n",t2.val[root]+TAG);
} return 0;
}

洛谷.3273.[SCOI2011]棘手的操作(左偏树)的更多相关文章

  1. 洛谷P3273 [SCOI2011] 棘手的操作 [左偏树]

    题目传送门 棘手的操作 题目描述 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边,连接第x个节点和第y个节点 A1 ...

  2. 洛谷P4331 [BOI2004] Sequence 数字序列 [左偏树]

    题目传送门 数字序列 题目描述 给定一个整数序列 a1​,a2​,⋅⋅⋅,an​ ,求出一个递增序列 b1​<b2​<⋅⋅⋅<bn​ ,使得序列 ai​ 和 bi​ 的各项之差的绝对 ...

  3. 模板 可并堆【洛谷P3377】 【模板】左偏树(可并堆)

    P3377 [模板]左偏树(可并堆) 如题,一开始有N个小根堆,每个堆包含且仅包含一个数.接下来需要支持两种操作: 操作1: 1 x y 将第x个数和第y个数所在的小根堆合并(若第x或第y个数已经被删 ...

  4. 洛谷P3066 [USACO12DEC] 逃跑的Barn [左偏树]

    题目传送门 逃跑的Barn 题目描述 It's milking time at Farmer John's farm, but the cows have all run away! Farmer J ...

  5. 洛谷$P4331\ [BOI2004]\ Sequence$ 数字序列 左偏树

    正解:左偏树 解题报告: 传送门$QwQ$ 开始看到的时候$jio$得长得很像之前做的一个$dp$,,, 但是$dp$那题是说不严格这里是严格? 不难想到我们可以让$a_{i},b_{i}$同时减去$ ...

  6. bzoj2333[SCOI2011]棘手的操作 洛谷P3273 [SCOI2011]棘手的操作

    2333? 先记一下吧,这题现在全部都是照着题解做的,因为怎么改都改不出来,只好对着题解改,以后还要再做过 以后再也不用指针了!太恶心了!空指针可不止直接特判那么简单啊,竟然还要因为空指针写奇怪的分类 ...

  7. 洛谷P3273 [SCOI2011]棘手的操作

    题目描述 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作:U x y: 加一条边,连接第x个节点和第y个节点A1 x v: 将第x个节点的权 ...

  8. 洛谷P3261 [JLOI2015]城池攻占(左偏树)

    传送门 每一个城市代表的点开一个小根堆,把每一个骑士合并到它开始攻占的城池所代表的点上 然后开始dfs,每一次把子树里那些还活着的骑士合并上来 然后再考虑当前点的堆,一直pop直到骑士全死光或者剩下的 ...

  9. 2333: [SCOI2011]棘手的操作[离线线段树]

    2333: [SCOI2011]棘手的操作 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2325  Solved: 909[Submit][Stat ...

随机推荐

  1. Python爬虫-爬取百度贴吧帖子

    这次主要学习了替换各种标签,规范格式的方法.依然参考博主崔庆才的博客. 1.获取url 某一帖子:https://tieba.baidu.com/p/3138733512?see_lz=1&p ...

  2. libevent 和 libev 提高网络应用性能

    构建现代的服务器应用程序需要以某种方法同时接收数百.数千甚至数万个事件,无论它们是内部请求还是网络连接,都要有效地处理它们的操作.有许多解决方 案,但是 libevent 库和 libev 库能够大大 ...

  3. headers 替换脚本

    python代码 headers = """ Accept: */* Accept-Encoding: gzip, deflate, br Accept-Language ...

  4. Mashup

    简介 mashup是糅合,是当今网络上新出现的一种网络现象,将两种以上使用公共或者私有数据库的web应用,加在一起,形成一个整合应用.一般使用源应用的API接口,或者是一些rss输出(含atom)作为 ...

  5. MySQL数据库——安装教程(5.7版本)

    一.配置MySQL数据库 1.解压绿色版mysql,并改名为mysql5.7,如下图 对比一下下图5.6以前的版本,少data目录(存放数据)和my-default.ini文件(配置信息) 二.安装服 ...

  6. 003_Linux的Cgroup<实例详解>

    为什么要有cgroup Linux系统中经常有个需求就是希望能限制某个或者某些进程的分配资源.也就是能完成一组容器的概念,在这个容器中,有分配好的特定比例的cpu时间,IO时间,可用内存大小等.于是就 ...

  7. jdk写webservice

    jdk写webservice 1.定义一个需要发布的类,使用@WebService注解. 2.需要发布的方法可以不用@WebMethod注解,如果需要改变访问方法名,可用@WebMethod修改. 3 ...

  8. linux设备模型:扩展篇

    Linux设备模型组件:总线  一.定义:总线是不同IC器件之间相互通讯的通道;在计算机中,一个总线就是处理器与一个或多个不同外设之间的通讯通道;为了设备模型的目的,所有的设备都通过总线相互连接,甚至 ...

  9. asp.net core 通过ajax上传图片及wangEditor图片上传

    asp.net core 通过ajax上传图片 .net core前端代码,因为是通过ajax调用,首先要保证ajax能调用后台代码,具体参见上一篇.net core 使用ajax调用后台代码. 前端 ...

  10. OCM_第九天课程:Section4—》OCM课程环境搭建

    注:本文为原著(其内容来自 腾科教育培训课堂).阅读本文注意事项如下: 1:所有文章的转载请标注本文出处. 2:本文非本人不得用于商业用途.违者将承当相应法律责任. 3:该系列文章目录列表: 一:&l ...