POJ 2985 The k-th Largest Group(树状数组 并查集/查找第k大的数)
| Time Limit: 2000MS | Memory Limit: 131072K | |
| Total Submissions: 8690 | Accepted: 2847 |
Description
Newman likes playing with cats. He possesses lots of cats in his home. Because the number of cats is really huge, Newman wants to group some of the cats. To do that, he first offers a number to each of the cat (1, 2, 3, …, n). Then he occasionally combines the group cat i is in and the group cat j is in, thus creating a new group. On top of that, Newman wants to know the size of the k-th biggest group at any time. So, being a friend of Newman, can you help him?
Input
1st line: Two numbers N and M (1 ≤ N, M ≤ 200,000), namely the number of cats and the number of operations.
2nd to (m + 1)-th line: In each line, there is number C specifying the kind of operation Newman wants to do. If C = 0, then there are two numbers i and j (1 ≤ i, j ≤ n) following indicating Newman wants to combine the group containing the two cats (in case these two cats are in the same group, just do nothing); If C = 1, then there is only one number k (1 ≤ k ≤ the current number of groups) following indicating Newman wants to know the size of the k-th largest group.
Output
For every operation “1” in the input, output one number per line, specifying the size of the kth largest group.
Sample Input
10 10 0 1 2 1 4 0 3 4 1 2 0 5 6 1 1 0 7 8 1 1 0 9 10 1 1
Sample Output
1 2 2 2 2
Hint
When there are three numbers 2 and 2 and 1, the 2nd largest number is 2 and the 3rd largest number is 1.
思路
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 200005;
int N,root[maxn],a[maxn],c[maxn];
int find(int x)
{
if (root[x] != x) root[x] = find(root[x]);
return root[x];
}
int find_kth(int x) //查找第k小的元素
{
int ans = 0,cnt = 0;
for (int i = 20;i >= 0;i--) //这里的20适当的取值,与MAX_VAL有关,一般取lg(MAX_VAL)
{
ans += (1 << i);
if (ans > N || cnt + c[ans] >= x)
ans -= (1 << i);
else
cnt += c[ans];
}
return ans + 1;
}
void upd(int i,int v)
{
while (i <= N)
{
c[i] += v;
i += i & -i;
}
}
int main()
{
int M;
while (~scanf("%d%d",&N,&M))
{
int tot = N;
memset(c,0,sizeof(c));
for (int i = 1;i <= N;i++) root[i] = i,a[i] = 1; //a[i]表示编号为i的Group大小
upd(1,N); //初始Group大小为1的有N个
while (M--)
{
int opt,x,y;
scanf("%d",&opt);
if (opt == 0)
{
scanf("%d%d",&x,&y);
x = find(x);
y = find(y);
if (x == y) continue;
upd(a[x],-1);
upd(a[y],-1); //x与y合并,则编号为x的Group与编号为y的Group大小减1
upd(a[x] + a[y],1); //大小为a[x]+a[y]的Group的大小增1
root[y] = x; //y的祖先节点为x;
a[x] += a[y]; //编号为x的Group大小增加a[y]
tot--; //并查集合并,则总元素减少1
}
else
{
scanf("%d",&x);
printf("%d\n",find_kth(x));
}
}
}
return 0;
}
POJ 2985 The k-th Largest Group(树状数组 并查集/查找第k大的数)的更多相关文章
- [BZOJ3038]上帝造题的七分钟2 树状数组+并查集
考试的时候用了两个树状数组去优化,暴力修改,树状数组维护修改后区间差值还有最终求和,最后骗了40分.. 这道题有好多种做法,求和好说,最主要的是开方.这道题过的关键就是掌握一点:在数据范围内,最多开方 ...
- poj 2985 The k-th Largest Group 树状数组求第K大
The k-th Largest Group Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 8353 Accepted ...
- POJ2985 The k-th Largest Group[树状数组求第k大值+并查集||treap+并查集]
The k-th Largest Group Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 8807 Accepted ...
- luogu 4145 花神游历各国 线段树/树状数组+并查集
此题一看便是RMQ问题,但是由于开平方的特殊操作,tag操作失效 此时发现特性:sqrt最多执行6此便使值到达1/0,此时可以剪枝不进行该操作,利用并查集到达特性找根,根代表还可以进行操作的点,再利用 ...
- SPOJ GSS4 Can you answer these queries IV ——树状数组 并查集
[题目分析] 区间开方+区间求和. 由于区间开方次数较少,直接并查集维护下一个不是1的数的位置,然后暴力修改,树状数组求和即可. 这不是BZOJ上上帝造题7分钟嘛 [代码] #include < ...
- CodeVS2492 上帝造题的七分钟2(树状数组+并查集)
传送门 树状数组模板题.注意优化,假设某个数的值已经是1了的话.那么我们以后就不用对他进行操作了,这个能够用并查集实现. 这道题还有个坑的地方,给出查询区间端点的a,b,有可能a>b. #inc ...
- BZOJ 3211 花神游历各国 (树状数组+并查集)
题解:首先,单点修改求区间和可以用树状数组实现,因为开平方很耗时间,所以在这个方面可以优化,我们知道,开平方开几次之后数字就会等于1 ,所以,用数组记录下一个应该开的数,每次直接跳到下一个不是1的数字 ...
- BZOJ3211 花神游历各国 【树状数组 + 并查集】
题目 输入格式 输出格式 每次x=1时,每行一个整数,表示这次旅行的开心度 输入样例 4 1 100 5 5 5 1 1 2 2 1 2 1 1 2 2 2 3 1 1 4 输出样例 101 11 1 ...
- [BZOJ3211]花神游历各国&&[BZOJ3038] 上帝造题的七分钟2 树状数组+并查集
3211: 花神游历各国 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 4057 Solved: 1480[Submit][Status][Discu ...
随机推荐
- 工作随笔——一次简单的Maven加速构建实战
注意:所有的编译.打包.部署全部是通过Jenkins完成的. 公司内部有一个项目,开始做的时候已经预计到会有很多客服端.所以开发就搞了如下的结构: fft-api # 公用的API,所有的程序都必须使 ...
- 谈对象 MVC 和 多端
什么是对象? 我是单身狗,我没有对象:我是C程序猿,我没有对象:我是程序猿,我只会new一个对象. 言归正传,想想从一个电商网站上买一个东西,“进入首页,搜索商品,选型购买,登录下单,支付完成”,这里 ...
- 【算法之美】求解两个有序数组的中位数 — leetcode 4. Median of Two Sorted Arrays
一道非常经典的题目,Median of Two Sorted Arrays.(PS:leetcode 我已经做了 190 道,欢迎围观全部题解 https://github.com/hanzichi/ ...
- 学习Python的三种境界
前言 王国维在<人间词话>中将读书分为了三种境界:"古今之成大事业.大学问者,必经过三种之境界:'昨夜西风凋碧树,独上高楼,望尽天涯路'.此第一境也.'衣带渐宽终不悔,为伊消得人 ...
- matlab中的卷积——filter,conv之间的区别
%Matlab提供了计算线性卷积和两个多项式相乘的函数conv,语法格式w=conv(u,v),其中u和v分别是有限长度序列向量,w是u和v的卷积结果序列向量. %如果向量u和v的长度分别为N和M,则 ...
- TF2ZP函数
TF2ZP 中TF是什么意思? Transfer function tf 就是传递函数的意思,简称传函 tf2zp是将传递函数转换为零极点形式的一个转换函数 [Z,P,K] = TF2ZP ...
- [转]扩展RBAC用户角色权限设计方案
原文地址:http://www.iteye.com/topic/930648 RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联.简单地 ...
- eclipse汉化
一.准备工作: 1.eclipse点击help——about eclipse查看软件版本,如图: 2.登录官网语言包下载地址:http://www.eclipse.org/babel/download ...
- 【POJ 2774】Long Long Message 最长公共子串
还是模板啊,手残&&打成||查错查了1h+TAT #include<cstdio> #include<cstring> #include<algorith ...
- 从CIO、CEO、CFO、COO...到CVO 这22个你了解几个? (史上最完整版)
1.CEO:是Chief Executive Officer的缩写,即首席执行官. 由于市场风云变幻,决策的速度和执行的力度比以往任何时候都更加重要.传统的“董事会决策.经理层执行”的公司体制已经难以 ...