BZOJ2333 [SCOI2011]棘手的操作 堆 左偏树 可并堆
欢迎访问~原文出处——博客园-zhouzhendong
去博客园看该题解
题目传送门 - BZOJ2333
题意概括
有N个节点,标号从1到N,这N个节点一开始相互不连通。第i个节点的初始权值为a[i],接下来有如下一些操作:
U x y: 加一条边,连接第x个节点和第y个节点
A1 x v: 将第x个节点的权值增加v
A2 x v: 将第x个节点所在的连通块的所有节点的权值都增加v
A3 v: 将所有节点的权值都增加v
F1 x: 输出第x个节点当前的权值
F2 x: 输出第x个节点所在的连通块中,权值最大的节点的权值
F3: 输出所有节点中,权值最大的节点的权值
题解
我比较懒。
这是一道坑坑的细节题。
我调了大约6个小时。
对于A3,我们只需要保存一个全局变量,每次输出的时候加上去就可以了。
对于F3,我们只需要弄一个multiset就可以了。
对于U、A1、A2、F1、F2,就是左偏树的几个基本操作。
“嘴巴上AC就是简单”
代码
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <set>
#include <vector>
using namespace std;
const int N=300005,Inf=1e8;
int n,m,addv=0;
struct Tree{
int fa,ls,rs,v,add,len;
Tree (){}
Tree (int a,int b,int c,int d,int e,int f){
fa=a,ls=b,rs=c,v=d,add=e,len=f;
}
}t[N];
multiset <int> rts;
void check0(){
t[0]=Tree(0,0,0,-Inf,0,-1);
}
int getroot(int x){
check0();
while (t[x].fa)
x=t[x].fa;
return x;
}
void del(int x){
rts.erase(rts.find(x));
}
void pushdown(int x){
check0();
int s,&add=t[x].add;
if (!t[x].add)
return;
s=t[x].ls;
if (s)
t[s].add+=add,t[s].v+=add;
s=t[x].rs;
if (s)
t[s].add+=add,t[s].v+=add;
add=0;
}
void pushadd(int x){
check0();
if (t[x].fa)
pushadd(t[x].fa);
pushdown(x);
}
int merge(int a,int b){
check0();
if (a==b)
return a;
if (a==0)
return b;
if (b==0)
return a;
if (t[a].v<t[b].v)
swap(a,b);
pushdown(a);
t[a].rs=merge(t[a].rs,b);
t[t[a].rs].fa=a;
if (t[t[a].ls].len<t[t[a].rs].len)
swap(t[a].ls,t[a].rs);
t[a].len=t[t[a].rs].len+1;
return a;
}
void change(int x,int val){
check0();
pushadd(x);
int rt=getroot(x),maxv=t[rt].v;
int fa=t[x].fa,s=merge(t[x].ls,t[x].rs);
if (fa==0&&s==0){
del(t[x].v);
t[x].v=val;
rts.insert(t[x].v);
return;
}
t[s].fa=0;
if (fa){
t[s].fa=fa;
if (t[fa].ls==x)
t[fa].ls=s;
else
t[fa].rs=s;
}
t[x]=Tree(0,0,0,val,0,0);
merge(x,getroot(s?s:fa));
int maxv_=t[getroot(x)].v;
if (maxv_!=maxv){
del(maxv);
rts.insert(maxv_);
}
}
int main(){
scanf("%d",&n);
check0();
rts.clear();
for (int i=1,v;i<=n;i++){
scanf("%d",&v);
t[i]=Tree(0,0,0,v,0,0);
rts.insert(v);
}
scanf("%d",&m);
while (m--){
char op[5],c1,c2;
int a,b;
scanf("%s",op),c1=op[0],c2=op[1];
if (c1=='U'){
scanf("%d%d",&a,&b);
a=getroot(a),b=getroot(b);
if (a==b)
continue;
if (t[a].v<t[b].v)
swap(a,b);
del(t[b].v);
merge(a,b);
}
else if (c1=='A'){
if (c2=='1')
scanf("%d%d",&a,&b),pushadd(a),change(a,t[a].v+b);
else if (c2=='2'){
scanf("%d%d",&a,&b);
a=getroot(a);
del(t[a].v);
t[a].add+=b,t[a].v+=b;
rts.insert(t[a].v);
}
else
scanf("%d",&a),addv+=a;
}
else {
if (c2=='1')
scanf("%d",&a),pushadd(a),printf("%d\n",t[a].v+addv);
else if (c2=='2')
scanf("%d",&a),printf("%d\n",t[getroot(a)].v+addv);
else
printf("%d\n",*--rts.end()+addv);
} }
return 0;
}
BZOJ2333 [SCOI2011]棘手的操作 堆 左偏树 可并堆的更多相关文章
- 【BZOJ2333】棘手的操作(左偏树,STL)
[BZOJ2333]棘手的操作(左偏树,STL) 题面 BZOJ上看把... 题解 正如这题的题号 我只能\(2333\) 神TM棘手的题目... 前面的单点/联通块操作 很显然是一个左偏树+标记 ( ...
- Luogu P3273 [SCOI2011]棘手的操作(左偏树)
什么恶心东西啊,又水又烦 两个可并堆维护即可 #include <cstdio> #include <iostream> #include <cstring> #i ...
- 【BZOJ 2333 】[SCOI2011]棘手的操作(离线+线段树|可并堆-左偏树)
2333: [SCOI2011]棘手的操作 Description 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边 ...
- BZOJ2333 [SCOI2011]棘手的操作 【离线 + 线段树】
题目 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边,连接第x个节点和第y个节点 A1 x v: 将第x个节点的权 ...
- [note]左偏树(可并堆)
左偏树(可并堆)https://www.luogu.org/problemnew/show/P3377 题目描述 一开始有N个小根堆,每个堆包含且仅包含一个数.接下来需要支持两种操作: 操作1: 1 ...
- bzoj2809 [Apio2012]dispatching——左偏树(可并堆)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2809 思路有点暴力和贪心,就是 dfs 枚举每个点作为管理者: 当然它的子树中派遣出去的忍者 ...
- [bzoj2333] [SCOI2011]棘手的操作 (可并堆)
//以后为了凑字数还是把题面搬上来吧2333 发布时间果然各种应景... Time Limit: 10 Sec Memory Limit: 128 MB Description 有N个节点,标号从1 ...
- bzoj千题计划218:bzoj2333: [SCOI2011]棘手的操作
http://www.lydsy.com/JudgeOnline/problem.php?id=2333 上次那个是线段树,再发一个左偏树 维护两种左偏树 第一种是对每个联通块维护一个左偏树 第二种是 ...
- 【BZOJ 2333 】[SCOI2011]棘手的操作(离线+线段树)
2333: [SCOI2011]棘手的操作 Description 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边 ...
随机推荐
- [译]Quartz.NET 框架 教程(中文版)2.2.x 之第七课 触发监听器和作业任务监听器
第七课:触发监听器和作业任务监听器 监听器是在调度器中基于事件机制执行操作的对象.你大概可以猜到,触发监听器接收响应跟触发器有关的事件,作业任务监听器接收响应跟作业任务有关的事件. 跟触发器有关的事件 ...
- ettercap插件介绍
利用sslstrip和ettercap突破ssl嗅探密码 ettercap之DNS欺骗--结合metasploit使用 ettercap支持在运行时加载模块.它们会自动地编译你的系统是否支持他们或者直 ...
- 虚拟机centos7系统下安装hadoop ha和yarn ha(详细)
一:基础环境准备 (一):虚拟机新建五个centos7系统(复制文件夹的方式) (二):角色分配 (三)按照角色分配表配置 (1)更改主机ip(自行查找),如果只是个人搭建玩一玩,可选择安装cento ...
- AQS框架
java并发包基石 AQS是JUC中很多同步组件的构建基础,简单来讲,它内部实现主要是状态变量state和一个FIFO队列来完成,同步队列的头结点是当前获取到同步状态的结点,获取同步状态state失败 ...
- python - classs内置方法 solt
solt # __solt__ # 是一个类变量,变量值可以是列表.元组或者是可迭代对象,也可以是一个字符串 # (以为这所有实例只有一种数据属性) # # 作用:(为了节省内存空间,减少过多的实例属 ...
- 【逆向工具】逆向工具101editor使用-游戏快速通关
[渡者游戏简介] 船夫小江将运送客人的,羊.狐狸.草等物品过河,如果留下动物被其它种类吃掉任务就失败了.你需要帮助他做出正确的顺序选择.Ferryman是一款根据经典谜题改编的解谜游戏. 一.查看文件 ...
- mysql数据库查询库中所有表所占空间大小
SELECT CONCAT(table_schema,'.',table_name) AS 'TABLE_NAME', CONCAT(, ),'M') AS 'ROW_SIZE', CONCAT( ) ...
- git 使用https 和SSH 提交远程库小总结
一.使用https提交远程库 首先已经git commit -m “注释” 本地仓库关联远程github服务器:git remote add origin “https://XXXX.git” 提交 ...
- 学习笔记_Cocos Creator_继承组件单例
官方文档:https://docs.cocos.com/creator/manual/zh/scripting/reference/class.html 前言 单例,在游戏开发中是比较常用的功能,全局 ...
- skearn自学路径
sklearn学习总结(超全面) 关于sklearn,监督学习几种模型的对比 sklearn之样本生成make_classification,make_circles和make_moons pytho ...