The k-th Largest (并查集+线段树)
来源:互联网 发布:江西省网络诈骗 编辑:程序博客网 时间:2024/06/06 05:54
The k-th Largest Group
Time Limit: 2000msMemory Limit: 131072KB64-bit integer IO format: %lld Java class name:Main
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 catj is in, thus creating a new group. On top of that, Newman wants to know the size of thek-th biggest group at any time. So, being a friend of Newman, can you help him?
Time Limit: 2000ms
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 catj is in, thus creating a new group. On top of that, Newman wants to know the size of thek-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. IfC = 0, then there are two numbersi 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); IfC = 1, then there is only one numberk (1 ≤ k ≤ the current number of groups) following indicating Newman wants to know the size of thek-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 100 1 21 40 3 41 20 5 61 10 7 81 10 9 101 1
Sample Output
12222
/**********************************************************************************************************************************************************************
关于线段树的经验总结:
1.一系列的操作都用递归实现
2.无论构造还是更新线段树,都应该传入一个 "int node" 也就是虚拟的节点
还要传入 int left 和 int right 来作为要写入线段树的原始的数据域
3.构造函数:首先用if()语句判断结束条件 利用递归构造左右子树 回溯得到节点信息
其中的重要操作 1. 左子树 -> node * 2(node << 2)
2. 右子树 -> node * 2 + 1(node << 2 | 1)
3. 重要的结束条件 即 left == right
4.要理解每一个node对应一个独立的区间
**********************************************************************************************************************************************************************/
#include <cstdio>#include <string.h>int const Max = 200000;int seg[Max * 4 + 10];int num[Max +5];int pre[Max + 5];int n;int findp(int x){//寻找祖先 while(pre[x] != x){ x = pre[x]; } return x;}void build(int node, int l, int r){ if(l == 1) seg[node] = n; else seg[node] = 0; if(l == r) return; //构建左右子树 build(node * 2, l, (l + r) / 2); build(node * 2 + 1, (l + r) / 2 + 1, r);}void update(int pos, int cc, int node, int l, int r){//假如要把i和j所在的团队合并,那么先找到i和j所在的区间段,把这个段的值各-1, 然后再找到i+j所在的区间段,把这个区间段的值+1 seg[node] += cc; if(l == r) return; if(pos <= (l + r) / 2) update(pos, cc, node * 2, l, (l + r) / 2); else update(pos, cc, node * 2 + 1, (l + r) / 2 + 1, r);}int query(int pos, int node, int l, int r){//需要查询的是第k大的队伍 if(l == r) return l; if(seg[node * 2 + 1] >= pos) return query(pos, node * 2 + 1, (l + r) / 2 + 1, r); else return query(pos - seg[node * 2 + 1], node * 2, l, (l + r) / 2);}int main(){ int m, a, b, c, k; scanf("%d %d", &n, &m); for(int i = 1; i <= n; i++ ){ pre[i] = i; num[i] = 1; } for(int i = 1; i <= m; i++){ scanf("%d", &c); if(c == 0){ scanf("%d %d", &a, &b); int x = findp(a); int y = findp(b); if(x == y) continue; update(num[x], -1, 1, 1, n); update(num[y], -1, 1, 1, n); update(num[x] + num[y], 1, 1, 1, n); num[x] += num[y]; pre[y] = x; } else{ scanf("%d", &k); printf("%d\n", query(k, 1, 1, n)); } } return 0;}
- The k-th Largest (并查集+线段树)
- poj 2985 并查集+线段树 线段树求第k大数 The k-th Largest Group
- PKU2985(The k-th Largest Group)线段树+并查集
- poj 2985 The k-th Largest Group(线段树+并查集)
- POJ 题目2985 The k-th Largest Group(线段树单点更新求第k大值,并查集)
- POJ2985 The k-th Largest Group(treap+并查集)
- Treap树(并查集 + 树堆)POJ —— 2985 The k-th Largest Group
- poj 2985 The k-th Largest Group (并查集x全局动态第k大)
- poj 2985 The k-th Largest Group 并查集+树状数组求第k大
- POJ 2985 The k-th Largest Group 第k大数 Treap / 树状数组 + 并查集
- poj 2985 The k-th Largest Group/并查集+sbt
- poj 2985 The k-th Largest Group (Treap+并查集)
- POJ 2985The k-th Largest Group 线段树求整体第K大
- POJ 2985 The k-th LargestGroup(Treap+并查集)
- POJ 2985 The k-th LargestGroup(Treap+并查集)
- The K-th largest number(小根堆)
- POJ 2985 The k-th Largest Group [并差集+treap]
- poj2985(名次树(treap))找第k大 The k-th Largest Group
- [暑假集训] jzoj 2016.7.7 noip模拟赛C 总结
- MFC使用ADO链接ACCESS的环境部署与注意事项
- adcmctl.sh wait=Y
- UGUI中层级关系
- YL杯超级篮球赛 (Standard IO)
- The k-th Largest (并查集+线段树)
- poj 3268 Silver Cow Party 题解
- Selenium2: web元素定位方法笔记
- LINUX经典书籍
- JS正则表达式-test()方法的使用
- YL杯超级篮球赛_纪中_1325
- linux gcc链接完程序后,运行程序发现找不到*.so
- Android菜鸟学步之AIDL
- c++——static关键字