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 ...
随机推荐
- Spring初始化日志
Spring启动时的日志: 2013-11-22 14:55:59:319[INFO]: FrameworkServlet 'spring3': initialization completed in ...
- php对图片加水印--将图片先缩小,再在上面加水印
方法: /** * 图片加水印(适用于png/jpg/gif格式) * * @author flynetcn * * @param $srcImg 原图片 * @param $water ...
- sublime text 3 3143注册码
1.点击help->enter license: —– BEGIN LICENSE —– TwitterInc 200 User License EA7E-890007 1D77F72E 390 ...
- Lucene学习之四:Lucene的索引文件格式(2)
本文转载自:http://www.cnblogs.com/forfuture1978/archive/2009/12/14/1623599.html 略有删减和补充 四.具体格式 上面曾经交代过,L ...
- Go.网络篇-2
package main import ( "io/ioutil" "os" "io" "log" "net/ ...
- 分布式事务概述--2pc的概念
转载自一个大拿:http://www.cnblogs.com/LBSer/p/4715395.html 前阵子从支付宝转账1万块钱到余额宝,这是日常生活的一件普通小事,但作为互联网研发人员的职业病,我 ...
- linux系统下部署项目
一.修改防火墙设置,开放对应的端口 修改Linux系统防火墙配置需要修改 /etc/sysconfig/iptables 这个文件,如果要开放哪个端口,在里面添加一条 -A RH-Firewall- ...
- CSS3之 :nth-child(n)语法讲解
语法: E:nth-child(n){ sRules } * 匹配父元素索引为n的子元素E :nth-child(n) 让你匹配到父元素的任一子元素: Figure 1:<section id= ...
- php扩展库
php调用C/C++动态链接库 字数997 阅读28 评论0 喜欢0 本人最近在找实习,移动开发方向.有意者可直接与本人联系.谢谢! 一.简介 一般而言,php速度已经比较快,但是,对于一些较高级开发 ...
- CSS3及JS简单实现选项卡效果(适配手机端和pc端)
想要适配手机端和pc端,有几种简单的方法,本人使用的是百分比分配的方法. *{ padding: 0; margin: 0; } body,html{ width: 100%; height: 100 ...