[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) ...
随机推荐
- directX根据设备类GUID查询所属的filter
hr = m_pSysDevEnum->CreateClassEnumerator(*clsid, &pEnumCat, 0); ASSERT(SUCCEEDED(hr)); ...
- 利用MD5加密字符串
private static string MD5E(string temp) { MD5 md5 = new MD5CryptoServiceProvider(); byte[] source=Sy ...
- angular路由操作中'#'字符的解决办法
var app=angular.module("myapp",["ngRoute"]);app.controller("ctr",funct ...
- Ajax前后台交互函数
function AJAX(obj){ //做网络请求的时候参数以对象的形式传递进来 //我们规定obj里面包含属性:url, //请求方式type, //date前端给后端传递的参数 //回调函数s ...
- Docker 入门之swarm部署web应用
笔者近期在利用的docker搭建一个swarm集群,目前的应用还是入门级的,读者可自行根据自己的需要修改自己需要部署的应用,今天笔者介绍的是一个web应用的swarm集群的搭建.看这篇文章之前,我希望 ...
- Alice and Bob HDU - 4268
Alice and Bob's game never ends. Today, they introduce a new game. In this game, both of them have N ...
- Mac 常用快捷键
可以按下组合键来实现通常需要鼠标.触控板或其他输入设备才能完成的操作. 要使用键盘快捷键,需按住一个或多个修饰键,同时按快捷键的最后一个键.例如,要使用快捷键 Command-C(拷贝),请按住 Co ...
- select选中获取索引三种写法
$('#someId').prop('selectedIndex'); $('option:selected', '#someId').index(); $('#someId option').ind ...
- 英文汉语切换的导航栏,纯css制作。
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- FTP环境搭建及客户代码调用公共方法封装
一.背景 大型系统架构往往被分解为多个独立可运行的组件, 以满足性能.可靠性.可扩展性的需求.多个组件间的数据交互往往采用两种方式:小量数据通过Sock函数.RMI.WebService等接口方式传递 ...