[poj-2985]The k-th Largest Group_Treap+并查集
The k-th Largest Group poj-2985
题目大意:给你n只猫,有两种操作:1.将两只猫所在的小组合并。2.查询小组数第k大的小组的猫数。
注释:1<=n,m<=200,000.
想法:开始的想法就是用Treap合并,用Treap删除。然后发现Treap合并实在是...太tm gay了。没办法,用并查集吧。想法就出现了,我们用并查集合并,用Treap查询k大值。考虑怎么实现:因为我们想用Treap查询k大值,所以我们Treap中维护的一定是集合中猫的个数。并查集的合并呢?我们可以只在并查集森林的根节点处维护每一颗并查集的节点数。用并查集直接合并就行,我们考虑如何进行Treap中的修改?我们可以先把两只猫的集合先删掉,然后在加入一个两只猫集合总数的节点即可。那么,这题就切了吗对不对... ...
最后,附上丑陋的代码... ...
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int tot,root;
int number[400010];
int fa[400010];
struct Node
{
int lson,rson;
int size,num;
int val,rnd;
}a[400010];
inline void update(int k)
{
a[k].size=a[a[k].lson].size+a[a[k].rson].size+a[k].num;
}
void lturn(int &k)
{
int t=a[k].rson;
a[k].rson=a[t].lson;
a[t].lson=k;
update(k);update(t);k=t;
}
void rturn(int &k)
{
int t=a[k].lson;
a[k].lson=a[t].rson;
a[t].rson=k;
update(k);update(t);k=t;
}
void insert(int &k,int temp)
{
if(!k)
{
k=++tot;
a[k].num=a[k].size=1;
a[k].val=temp;
a[k].rnd=rand();
return;
}
a[k].size++;
if(temp==a[k].val) a[k].num++;
else if(temp<a[k].val)
{
insert(a[k].lson,temp);update(k);
if(a[a[k].lson].rnd<a[k].rnd) rturn(k);
}
else
{
insert(a[k].rson,temp);update(k);
if(a[a[k].rson].rnd<a[k].rnd) lturn(k);
}
}
void del(int &k,int temp)
{
if(!k) return;
if(temp==a[k].val)
{
if(a[k].num>1)
{
a[k].num--;
a[k].size--;
}
else if(a[k].lson==0||a[k].rson==0)
{
k=a[k].lson+a[k].rson;
}
else if(a[a[k].lson].rnd<a[a[k].rson].rnd)
{
rturn(k);
del(k,temp);
}
else
{
lturn(k);
del(k,temp);
}
}
else if(temp<a[k].val)
{
a[k].size--;
del(a[k].lson,temp);
}
else
{
a[k].size--;
del(a[k].rson,temp);
}
}
int ask_num(int k,int temp)
{
if(k<=0||temp<=0) return 0;
if(temp<=a[a[k].lson].size) return ask_num(a[k].lson,temp);
else if(temp>a[a[k].lson].size+a[k].num)
{
return ask_num(a[k].rson,temp-a[k].num-a[a[k].lson].size);
}
else return a[k].val;
}
int find(int x)
{
return fa[x]==x?x:(fa[x]=find(fa[x]));
}
void merge(int x,int y)
{
x=find(x);y=find(y);
fa[x]=y;
number[y]+=number[x];
}
void original()
{
memset(a,0,sizeof a);
root=0;
tot=0;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
original();
for(int i=1;i<=n;i++)
{
fa[i]=i;
number[i]=1;
}
root=1;
tot=1;
a[1].val=1;
a[1].size=a[1].num=n;
a[1].rnd=rand();
int flag;
int x,y;
for(int i=1;i<=m;i++)
{
scanf("%d",&flag);
if(!flag)
{
scanf("%d%d",&x,&y);
if(find(x)==find(y)) continue;
del(root,number[find(x)]);
del(root,number[find(y)]);
insert(root,number[find(x)]+number[find(y)]);
merge(x,y);
}
else
{
scanf("%d",&x);
printf("%d\n",ask_num(root,a[root].size-x+1));
}
}
}
}
小结:我的并查集最后写错了,导致调了5h... ...
[poj-2985]The k-th Largest Group_Treap+并查集的更多相关文章
- 51 nod 1456 小K的技术(强连通 + 并查集)
1456 小K的技术 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 苏塞克王国是世界上创新技术的领先国家,在王国中有n个城市 ...
- POJ 1988 Cube Stacking( 带权并查集 )*
POJ 1988 Cube Stacking( 带权并查集 ) 非常棒的一道题!借鉴"找回失去的"博客 链接:传送门 题意: P次查询,每次查询有两种: M x y 将包含x的集合 ...
- poj 1733 Parity game(带权并查集+离散化)
题目链接:http://poj.org/problem?id=1733 题目大意:有一个很长很长含有01的字符串,长度可达1000000000,首先告诉你字符串的长度n,再给一个m,表示给你m条信息, ...
- POJ:1182 食物链(带权并查集)
http://poj.org/problem?id=1182 Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1 ...
- poj 1182 食物链 (带关系的并查集)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 44835 Accepted: 13069 Description 动 ...
- poj 1703 Find them, Catch them 【并查集 新写法的思路】
题目地址:http://poj.org/problem?id=1703 Sample Input 1 5 5 A 1 2 D 1 2 A 1 2 D 2 4 A 1 4 Sample Output N ...
- POJ2985 The k-th Largest Group (并查集+treap)
Newman likes playing with cats. He possesses lots of cats in his home. Because the number of cats is ...
- POJ 1182 食物链 (经典带权并查集)
第三次复习了,最经典的并查集 题意:动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们 ...
- [POJ 1988] Cube Stacking (带值的并查集)
题目链接:http://poj.org/problem?id=1988 题目大意:给你N个方块,编号从1到N,有两种操作,第一种是M(x,y),意思是将x所在的堆放到y所在的堆上面. 第二种是C(x) ...
随机推荐
- FusionCharts 2D柱状图和折线图的组合图
1.设计思路 (1)了解组合图的特性以及用法,选用图的类型: (2)设计出两根柱子和两根折线,分开展示. 2.设计步骤 (1)设计页面 Column2DLine.html: <!DOCTYPE ...
- linux下FFmpeg编译生成ffplay
1.确认Makefile中指定的config.mak(在ffmpeg根目录下)中:CONFIG_FFPLAY=yes,如果不是需要重新./configure 该处还有ffmpeg.ffprobe.ff ...
- php学习笔记upset函数。
如果在函数中我们不希望再使用某个变量.可以使用unset()销毁函数, ②在php函数中,我们可以给某些参数赋一个默认初值. ③可以传一个默认的参数. ④php在传递变量的时候,默认是传递值传递,如果 ...
- eclipse中的System.getProperty("user.dir")
eclipse中的System.getProperty("user.dir") 1.在Java Application中,上述中的获取的是Java项目的路径 (1)运行源码 /** ...
- html中的块元素和内联元素的区别
一.定义 块元素一般都从新行开始,它可以容纳内联元素和其他块元素,可设置高度.宽度和边距等. 内联元素一般都是基于语义级的基本元素,它只能容纳文本或其他内联元素,主要特点是:和其他元素位于同一行上,高 ...
- 拥抱.NET Core系列:MemoryCache 缓存域
在上一篇“<拥抱.NET Core系列:MemoryCache 缓存选项>”我们介绍了一些 MSCache 的机制,今天我们来介绍一下 MSCache 中的缓存域. MSCache项目 M ...
- C#多线程编程(3)--开启子任务
上一篇我讲解了await和async关键字,这两个关键字的作用是将async限定的方法中await关键字后面的部分封装成一个委托,该委托会在await修饰的Task完成后再执行.简单的说,就是等待任务 ...
- 在VCS仿真器中使用FSDB
FSDB(Fast Signal Database)是Verdi支持的文件格式,用于保存仿真产生的信号波形.据Verdi文档说明,FSDB比标准的VCD格式节省磁盘空间,处理速度更快.要用VCS仿真器 ...
- 如何使用mysqldump备份数据库
一.背景 在开发项目中,数据库是核心资产.除了做主备冗余增加可靠性外,定期备份数据也是必须的. 使用mysqldump备份数据具有操作简单,备份和恢复时间短的优点(mysqldump备份数据生成的是批 ...
- Angular4---起步----环境配置安装@angular/cli
学习angular,首先要搭建起angular的手脚架@angular/cli.首先需要NodeJS环境. 1.安装NodeJS 首先检查电脑是否安装了NodeJS环境,打开cmd命令行,运行node ...