BZOJ2333:[SCOI2011]棘手的操作(Splay)
Description
有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: 输出所有节点中,权值最大的节点的权值
Input
输入的第一行是一个整数N,代表节点个数。
接下来一行输入N个整数,a[1], a[2], …, a[N],代表N个节点的初始权值。
再下一行输入一个整数Q,代表接下来的操作数。
最后输入Q行,每行的格式如题目描述所示。
Output
对于操作F1, F2, F3,输出对应的结果,每个结果占一行。
Sample Input
0 0 0
8
A1 3 -20
A1 2 20
U 1 3
A2 1 10
F1 3
F2 3
A3 -10
F3
Sample Output
10
10
HINT
对于30%的数据,保证 N<=100,Q<=10000
对于80%的数据,保证 N<=100000,Q<=100000
对于100%的数据,保证 N<=300000,Q<=300000
对于所有的数据,保证输入合法,并且 -1000<=v, a[1], a[2], …, a[N]<=1000
Solution
第一眼:这不splay启发式合并板子题吗?
然后就开始漫长的写写写调调调
维护多颗splay
U:splay启发式合并,一个个删除小的splay插入到大的splay里面
A1:删除val[x],插入val[x]+v
A2:开个Add数组,维护每颗splay整体加的数
A3:搞个全局变量ALL记一下就好了
F1:直接输出val[x]+Add[x]+ALL
F2:直接输出Max[ID[x]],其中ID是x所属的平衡树编号
F3::这个相当于要维护Max[]的最大值。开个可删堆,每次Max[i]变化的时候就把旧的删掉,新的插入,F3查询的时候直接输出堆顶即可。
emmm话说为什么大部分人都写的堆啊_(Xз」∠)_
Code
#include<iostream>
#include<cstdio>
#include<queue>
#define N (600000+1000)
using namespace std; int Son[N][],Father[N],Size[N];
int ID[N],Add[N],Val[N],Max[N];
int Root[N],n,m,x,y,v,ALL;
char opt[];
priority_queue<int>Heap,Del; int Get(int x){return Son[Father[x]][]==x;}
void Update(int x){Size[x]=Size[Son[x][]]+Size[Son[x][]]+;}
void Clear(int x){Son[x][]=Son[x][]=Father[x]=Size[x]=Val[x]=;} int Pre(int x)
{
x=Son[x][];
while (Son[x][]) x=Son[x][];
return x;
} int Get_Max(int x)
{
while (Son[x][]) x=Son[x][];
return Val[x];
} void Rotate(int x)
{
int wh=Get(x);
int fa=Father[x], fafa=Father[fa];
if (fafa) Son[fafa][Son[fafa][]==fa]=x;
Son[fa][wh]=Son[x][wh^]; Father[fa]=x;
if (Son[fa][wh]) Father[Son[fa][wh]]=fa;
Son[x][wh^]=fa; Father[x]=fafa;
Update(fa); Update(x);
} void Splay(int x)
{
for (int fa; (fa=Father[x]); Rotate(x))
if (Father[fa])
Rotate(Get(fa)==Get(x)?fa:x);
Root[ID[x]]=x;
} void Insert(int x,int y,int v)
{
int now=Root[ID[y]],fa=;
while ()
{
fa=now,now=Son[now][v>Val[now]];
if (now==)
{
Val[x]=v; Size[x]=; Father[x]=fa; ID[x]=ID[y];
Son[fa][v>Val[fa]]=x; Splay(x); return;
}
}
} void Delete(int x)
{
Splay(x);
if (!Son[Root[ID[x]]][] && !Son[Root[ID[x]]][])
{
Clear(Root[ID[x]]);
Root[ID[x]]=;
return;
}
if (!Son[Root[ID[x]]][])
{
Root[ID[x]]=Son[Root[ID[x]]][];
Clear(Father[Root[ID[x]]]);
Father[Root[ID[x]]]=;
return;
}
if (!Son[Root[ID[x]]][])
{
Root[ID[x]]=Son[Root[ID[x]]][];
Clear(Father[Root[ID[x]]]);
Father[Root[ID[x]]]=;
return;
}
int oldroot=Root[ID[x]];
int pre=Pre(Root[ID[x]]);
Splay(pre);
Son[Root[ID[x]]][]=Son[oldroot][];
Father[Son[oldroot][]]=Root[ID[x]];
Clear(oldroot);
Update(Root[ID[x]]);
} void Merge(int x,int y)
{
if (Son[x][]) Merge(Son[x][],y);
if (Son[x][]) Merge(Son[x][],y);
int val=Val[x]+Add[ID[x]]-Add[ID[y]]; Clear(x);
Insert(x,y,val);
} int main()
{
scanf("%d",&n);
for (int i=; i<=n; ++i)
{
scanf("%d",&x);
ID[i]=i; Val[i]=x; Max[i]=x;
Root[i]=i; Size[i]=; Heap.push(x);
}
scanf("%d",&m);
for (int i=; i<=m; ++i)
{
scanf("%s",opt);
if (opt[]=='U')
{
scanf("%d%d",&x,&y);
if (ID[x]!=ID[y])
{
Del.push(min(Max[ID[x]],Max[ID[y]]));
if (Size[Root[ID[x]]]>Size[Root[ID[y]]]) swap(x,y);
Max[ID[y]]=max(Max[ID[y]],Max[ID[x]]);
Merge(Root[ID[x]],Root[ID[y]]);
}
} if (opt[]=='A' && opt[]=='')
{
scanf("%d%d",&x,&v);
int val=Val[x]+v;
if (Size[Root[ID[x]]]==)
{
Val[x]=val;
Del.push(Max[ID[x]]);
Max[ID[x]]=val+Add[ID[x]];
Heap.push(Max[ID[x]]);
continue;
}
Delete(x); Insert(x,Root[ID[x]],val);
Del.push(Max[ID[x]]);
Max[ID[x]]=Get_Max(Root[ID[x]])+Add[ID[x]];
Heap.push(Max[ID[x]]);
} if (opt[]=='A' && opt[]=='')
{
scanf("%d%d",&x,&v), Add[ID[x]]+=v;
Del.push(Max[ID[x]]);
Max[ID[x]]=Get_Max(Root[ID[x]])+Add[ID[x]];
Heap.push(Max[ID[x]]);
} if (opt[]=='A' && opt[]=='')
scanf("%d",&v),ALL+=v; if (opt[]=='F' && opt[]=='')
scanf("%d",&x), printf("%d\n",Val[x]+Add[ID[x]]+ALL); if (opt[]=='F' && opt[]=='')
{
scanf("%d",&x), printf("%d\n",Max[ID[x]]+ALL);
} if (opt[]=='F' && opt[]=='')
{
while ((!Heap.empty()) && (!Del.empty()) && Heap.top()==Del.top())
Heap.pop(), Del.pop();
printf("%d\n",Heap.top()+ALL);
}
}
}
BZOJ2333:[SCOI2011]棘手的操作(Splay)的更多相关文章
- 真--可并堆模板--BZOJ2333: [SCOI2011]棘手的操作
n<=300000个点,开始是独立的,m<=300000个操作: 方法一:单点修改.查询,区间修改.查询?等等等等这里修改是块修改不是连续的啊,那就让他连续呗!具体方法:离线后,每次连接两 ...
- BZOJ2333 [SCOI2011]棘手的操作 堆 左偏树 可并堆
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2333 题意概括 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i ...
- [bzoj2333] [SCOI2011]棘手的操作 (可并堆)
//以后为了凑字数还是把题面搬上来吧2333 发布时间果然各种应景... Time Limit: 10 Sec Memory Limit: 128 MB Description 有N个节点,标号从1 ...
- bzoj千题计划217:bzoj2333: [SCOI2011]棘手的操作
http://www.lydsy.com/JudgeOnline/problem.php?id=2333 读入所有数据,先模拟一遍所有的合并操作 我们不关心联通块长什么样,只关心联通块内有谁 所以可以 ...
- 2019.01.17 bzoj2333: [SCOI2011]棘手的操作(启发式合并)
传送门 启发式合并菜题. 题意:支持与连通块有关的几种操作. 要求支持连边,单点修改,连通块修改,全局修改和单点查值,连通块查最大值和全局最大值. 我们对每个连通块和答案用可删堆维护最大值,然后用启发 ...
- BZOJ2333 [SCOI2011]棘手的操作 【离线 + 线段树】
题目 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边,连接第x个节点和第y个节点 A1 x v: 将第x个节点的权 ...
- bzoj2333 [SCOI2011]棘手的操作(洛谷3273)
题目描述 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作:U x y: 加一条边,连接第x个节点和第y个节点A1 x v: 将第x个节点的权 ...
- bzoj2333 [SCOI2011]棘手的操作
用set维护每个联通块里的最值,multiset维护所有块里的最值,并查集维护连通性,然后随便搞搞就行了,合并时候采用启发式合并.复杂度O(nlognlogn),大概勉强过的程度,反正跑的很慢就是了. ...
- (右偏树)Bzoj2333: [SCOI2011]棘手的操作
题面 戳我 Sol 右偏树滑稽+并查集 再在全局开一个可删除的堆(priority_queue) 注意细节 # include <bits/stdc++.h> # define RG re ...
随机推荐
- C# ASP.NET Core使用HttpClient的同步和异步请求
引用 Newtonsoft.Json // Post请求 public string PostResponse(string url,string postData,out string status ...
- ASP.NET Web API根据代码注释生成Help文档
使用Visual Studio新建一个ASP.NET Web API项目,直接运行,查看Help文档可以看到如下的API帮助说明 如何在Description中显示描述. 1. 打开Controlle ...
- 朝圣Java(问题集锦)之:The Apache Tomcat installation at this directory is version 8.5.32. A Tomcat 8.0 inst
最近开始学Java了.有C#底子,但是学起来Java还是很吃力,感觉别人架好了各种包,自己只要调用就行了,结果还有各种bug出现.掩面中. 启动Tomcat的时候,报错The Apache Tomca ...
- java_对象序列化、反序列化
1.概念 序列化:将对象转化为字节序列的过程 反序列化:将字节序列转化为对象的过程 用途: A:将对象转化为字节序列保存在硬盘上,如文件中,如文本中的例子就是将person对象序列化成字节序列,存在p ...
- input的属性用法介绍
Input表示Form表单中的一种输入对象,其又随Type类型的不同而分文本输入框,密码输入框,单选/复选框,提交/重置按钮等,下面一一介绍. 1,type=text 输入类型是text,这是我们见的 ...
- linux chkconfig 使用说明
原文 chkconfig是管理系统服务(service)的命令行工具.所谓系统服务(service),就是随系统启动而启动,随系统关闭而关闭的程序. chkconfig可以更新(启动或停止)和查询系统 ...
- IoDH 实现的单例模式
饿汉式单例类不能实现延迟加载,不管将来用不用始终占据内存:懒汉式单例类线程安全控制烦琐,而且性能受影响.有种更好的单例模式叫做Initialization Demand Holder (IoDH)的技 ...
- thinkphp更新数据库的时候where('')为字符串
if($user->where('phone='.$phone)->save($dataList)){} if($user->where(array('phone' =>$ph ...
- lib 和 dll
dll 和 lib只有在windows平台才会出现,老是忘记他们的区别和联系,记录一下,以备不时之需,也加深一下印象. 在弄懂两者的区别之前,需要知道两个概念: static library 和 d ...
- java unsupported major.minor version 51.0 解决
1.概述 出现如题所述异常 是因为jdk高版本 编译后的class文件 运行在低版本的jre环境下(如jdk7编译 运行在jdk6环境下) 2. 解决方案 在eclipse等ide中重新编译 指定编译 ...