[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) ...
随机推荐
- 错误代码: 1305 PROCEDURE world.insert_data does not exist
1.错误描述 1 queries executed, 0 success, 1 errors, 0 warnings 查询:call insert_data() 错误代码: 1305 PROCEDUR ...
- 列出JDK中常用的Java包
列出JDK中常用的Java包 1.java.lang 2.java.sql 3.java.io 4.java.math 5.java.text 6.java.net 7.java.util 8.jav ...
- 芝麻HTTP:pyspider的安装
pyspider是国人binux编写的强大的网络爬虫框架,它带有强大的WebUI.脚本编辑器.任务监控器.项目管理器以及结果处理器,同时支持多种数据库后端.多种消息队列,另外还支持JavaScript ...
- OpenStack_I版 5.Nova部署
Nova安装 创建配置存放目录,日志存放目录,执行文件目录,虚拟机目录 Nova配置修改 生成主配置文件 创建Nova数据库 同步Nova数据库 验证 Nova连接RabbitMQ配置修改 key ...
- ubuntu安装latex
1 终端中输入"sudo apt-get install texlive-full",输入root密码. 若不想安装所有文件,可以选择"sudo apt-get inst ...
- 小程序中点击input控件键盘弹出时placeholder文字上移
最近做的一个小程序项目中,出现了点击input控件键盘弹出时placeholder文字上移,刚开始以为是软键盘弹出布局上移问题是传说中典型的fixed 软键盘顶起问题,因此采纳了网上搜到的" ...
- SpringBean基础装配
首先,让我们先对Bean进行理解:什么是Bean,为什么要有Bean,如何装配Bean: 1,什么是Bean? Bean你可以看成是一个组件,在 ...
- 洛谷P1501 [国家集训队]Tree II(LCT,Splay)
洛谷题目传送门 关于LCT的其它问题可以参考一下我的LCT总结 一道LCT很好的练习放懒标记技巧的题目. 一开始看到又做加法又做乘法的时候我是有点mengbi的. 然后我想起了模板线段树2...... ...
- 【BZOJ4805】欧拉函数求和(杜教筛)
[BZOJ4805]欧拉函数求和(杜教筛) 题面 BZOJ 题解 好久没写过了 正好看见了顺手切一下 令\[S(n)=\sum_{i=1}^n\varphi(i)\] 设存在的某个积性函数\(g(x) ...
- 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](十一)
前言 小伙伴们, 大家好,我是Rector. 最近Rector忙于换工作,没有太多时间来更新我们的ASP.NET MVC 5系列文章 [一步一步创建ASP.NET MVC5程序Repository+A ...