BZOJ_1455_罗马游戏_可并堆
BZOJ_1455_罗马游戏_可并堆
Description
罗马皇帝很喜欢玩杀人游戏。 他的军队里面有n个人,每个人都是一个独立的团。最近举行了一次平面几何测试,每个人都得到了一个分数。 皇帝很喜欢平面几何,他对那些得分很低的人嗤之以鼻。他决定玩这样一个游戏。 它可以发两种命令: 1. Merger(i, j)。把i所在的团和j所在的团合并成一个团。如果i, j有一个人是死人,那么就忽略该命令。 2. Kill(i)。把i所在的团里面得分最低的人杀死。如果i这个人已经死了,这条命令就忽略。 皇帝希望他每发布一条kill命令,下面的将军就把被杀的人的分数报上来。(如果这条命令被忽略,那么就报0分)
Input
Output
如果命令是Kill,对应的请输出被杀人的分数。(如果这个人不存在,就输出0)
Sample Input
100 90 66 99 10
7
M 1 5
K 1
K 1
M 2 3
M 3 4
K 5
K 4
Sample Output
10
100
0
66
这里用左偏树实现可并堆。
左偏树是一种二叉数据结构,设$dis[x]$ 表示$x$ 节点一直向右走最多能走几步,满足$dis[lson]\ge dis[rson]$ 并且任何一个左偏树的左子树和右子树都是左偏树,我们让左偏树满足堆的性质,合并时总是往右儿子上合并,这样每次至少合并一半,使得复杂度能够保证。
对于这道题,我们用并查集维护一下每个人所在的团,并查集合并的同时合并两个左偏树,删除时让左子树右子树合并上来。
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stdlib.h>
using namespace std;
#define N 1000050
#define mr(x,y) make_pair(x,y)
#define fs first
#define sd second
int n,fa[N],kill[N],ls[N],rs[N],v[N],d[N];
char s[10];
int find(int x) {
return fa[x]==x?x:fa[x]=find(fa[x]);
}
int merge(int x,int y) {
if(!x) return y;
if(!y) return x;
if(v[x]>v[y]) swap(x,y);
rs[x]=merge(rs[x],y);
if(d[ls[x]]<d[rs[x]]) swap(ls[x],rs[x]);
d[x]=d[rs[x]]+1;
return x;
}
int main() {
scanf("%d",&n);
int i,x,y;
for(i=1;i<=n;i++) {
fa[i]=i; d[i]=1;
scanf("%d",&v[i]);
}
int m;
scanf("%d",&m);
while(m--) {
scanf("%s%d",s,&x);
if(s[0]=='M') {
scanf("%d",&y);
if(kill[x]||kill[y]) continue;
int dx=find(x),dy=find(y);
if(dx!=dy) {
fa[dx]=fa[dy]=merge(dx,dy);
}
}else {
if(kill[x]) {
puts("0");
continue;
}
int dx=find(x);
kill[dx]=1;
printf("%d\n",v[dx]);
int dy=merge(ls[dx],rs[dx]);
fa[dx]=fa[dy]=dy;
}
}
}
BZOJ_1455_罗马游戏_可并堆的更多相关文章
- [bzoj1455]罗马游戏_左偏树_并查集
罗马游戏 bzoj-1455 题目大意:给你n个人,2种操作,m次操作:1.将i号士兵所在的集合的最小值删除 2.合并i和j两个士兵所在的团体 注释:$1\le n\le 10^6$,$1\le m ...
- 【BZOJ 1455】 1455: 罗马游戏 (可并堆-左偏树+并查集)
1455: 罗马游戏 Description 罗马皇帝很喜欢玩杀人游戏. 他的军队里面有n个人,每个人都是一个独立的团.最近举行了一次平面几何测试,每个人都得到了一个分数. 皇帝很喜欢平面几何,他对那 ...
- 【BZOJ-1455】罗马游戏 可并堆 (左偏树)
1455: 罗马游戏 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1355 Solved: 561[Submit][Status][Discuss] ...
- 【bzoj1455】罗马游戏 可并堆
2016-05-31 10:04:41 可并堆的裸题. 左偏树(小根堆为例 性质 1.满足堆的性质,每个节点权值小于左右儿子权值 2.每个节点有dis值,表示子树最浅的叶子深度加1 3.左子树dis ...
- BZOJ 1455: 罗马游戏( 配对堆 + 并查集 )
可并堆水题 --------------------------------------------------------- #include<bits/stdc++.h> usin ...
- BZOJ 1455: 罗马游戏 [可并堆]
1455: 罗马游戏 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1715 Solved: 718[Submit][Status][Discuss] ...
- 1455: 罗马游戏[左偏树or可并堆]
1455: 罗马游戏 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1861 Solved: 798[Submit][Status][Discuss] ...
- C++之路进阶——bzoj1455(罗马游戏)
F.A.Qs Home Discuss ProblemSet Status Ranklist Contest ModifyUser gryz2016 Logout 捐赠本站 Notice:由于本OJ ...
- bzoj 1455: 罗马游戏 左偏树+并查集
1455: 罗马游戏 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 668 Solved: 247[Submit][Status] Descriptio ...
随机推荐
- spring boot + mybatis + druid配置实践
最近开始搭建spring boot工程,将自身实践分享出来,本文将讲述spring boot + mybatis + druid的配置方案. pom.xml需要引入mybatis 启动依赖: < ...
- DB2常用函数
1.char函数 char(current date,ISO)--转换成yyyy-mm-dd char(current date,USA)--转换成mm/dd/yyyy char(current ...
- InnoDB的4个特性
innodb 的四个特性 insert buffer innodb使用insert buffer"欺骗"数据库:对于为非唯一索引,辅助索引的修改操作并非实时更新索引的叶子页,而是把 ...
- Triangle (第8届山东省赛的某题)
triangle(第8届山东省赛的某题) 传送门 题意:喵了个呜,这题意真是峰回路转啊.懒死了,不想描述. 做法:我们拿set或线段树维护exp的最小值,每次取出exp值最小的边,删除之.并更新这条边 ...
- 关于react router 4 的小实践
详细代码栗子:https://github.com/wayaha/react-dom-CY clone然后 npm install npm start 分割线 1.这个项目使用create-react ...
- mysql-高级操作
主键冲突 主键冲突的时候,可以选择更新或者替换进行处理 更新 主键冲突,更新操作. Insert into 表名[(字段列表:包含主键)] values(值列表) on duplicate key u ...
- Prime 算法的简述
前面在介绍并查集时顺便提了Kruskal算法,既然已经说到了最小生成树问题,就没有道理不把Prime算法说了. 这里面先补充下Kruskal算法的大概意思,Kruskal算法通过把所有的边从小到大排列 ...
- 从一个微型例子看“C/C++的内存分配机制”和“数组变量名与指针变量名”(转)
C++的内存有五大分区:堆区.栈区.自由存储区.全局/静态存储区.常量存储区. 五个数据段:数据段.代码段.BSS段.堆.栈 内存分配方式有三种: 从静态存储区域分配.内存在程序编译的时候就已经分配好 ...
- Docker 多主机网络总结(非常全)
PS:文章首发公众号,欢迎大家关注我的公众号:aCloudDeveloper,专注技术分享,努力打造干货分享平台,二维码在文末可以扫,谢谢大家. 上篇文章介绍了容器网络的单主机网络,本文将进一步介绍多 ...
- vue实现双向数据绑定的原理
vue实现双向数据绑定的原理就是利用了 Object.defineProperty() 这个方法重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现的. 在MDN上对该方法的说明是:O ...