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 ≤ NM ≤ 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 ≤ ij ≤ 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.

Source

【分析】
这道题的正解是线段树,我只是拿来练个手而已。
写一遍直接交,狂T无压力....
Treap的常数实在是太大了,写了N遍,开始拿以为是内存池的问题.
尼玛开了内存池居然会比动态内存分配慢!!谁能告诉我为什么(╯‵□′)╯︵┻━┻。
好吧,关键不在这里...
treap写一般会t但是进行优化了以后还是可以过的。
只要不把大小为1的并查集加进去就可以了.........
 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <utility>
#include <iomanip>
#include <string>
#include <cmath>
#include <queue>
#include <assert.h>
#include <map>
#include <ctime>
#include <cstdlib> const int N = + ;
const int SIZE = ;//块状链表的大小
const int M = + ;
using namespace std;
struct TREAP{
struct Node{
int fix, size;
int val;
Node *ch[];
}mem[N], *root;
struct mem_poor{//内存池
queue<Node>Q;
void push(Node *t){//消除指针t所占用的地址
Q.push((*t));
}
Node* get(){
Node* t = &Q.front();
Q.pop();
return t;
}
}poor;
int tot, size;
//大随机
void init(){
// for (int i = 0; i <= 200000 + 5; i++)
//poor.Q.push(mem[i]);
size = ;
tot = ;
}
int BIG_RAND(){return rand();}
Node *NEW(){
Node *p = new Node;
p->fix = rand();//BIG_RAND();
p->size = ;
p->ch[] = p->ch[] = NULL;
return p;
}
//将t的d节点换到t
void rotate(Node *&t, int d){
Node *p = t->ch[d];
t->ch[d] = p->ch[d ^ ];
p->ch[d ^ ] = t;
t->size = ;
if (t->ch[] != NULL) t->size += t->ch[]->size;
if (t->ch[] != NULL) t->size += t->ch[]->size;
p->size = ;
if (p->ch[] != NULL) p->size += p->ch[]->size;
if (p->ch[] != NULL) p->size += p->ch[]->size;
t = p;
return;
}
void insert(Node *&t, int val){
//插入
if (t == NULL){
t = NEW();
t->val = val;
//size++;
return;
}
//大的在右边,小的在左边
int dir = (val >= t->val);
insert(t->ch[dir], val);
//维护最大堆的性质
if (t->ch[dir]->fix > t->fix) rotate(t, dir);
t->size = ;
if (t->ch[] != NULL) t->size += t->ch[]->size;
if (t->ch[] != NULL) t->size += t->ch[]->size;
}
//在t的子树中找到第k小的值
int kth(Node *t, int k){
if (t == NULL || k<= || k > t -> size) return ;
if (t->size == ) return t->val;
int l = ;//t的左子树中有多少值
if (t->ch[] != NULL) l += t->ch[]->size;
if (k == (l + )) return t->val;
if (k <= l) return kth(t->ch[], k);
else return kth(t->ch[], k - (l + ));
}
/*int find(Node *t, int val){
if (t == NULL) return 0;
int l = 0;//累加值
if (t->ch[0] != NULL) l += t->ch[0]->size;
if (val == t->val) return l + 1;
else if (val < t->val) return find(t->ch[0], val);
else return l + 1 + find(t->ch[1], val);
}*/
//找到值为val的节点
/*Node *&get(Node *&t, int val){
//if (t == NULL) return NULL;
if (val == t->val) return t;//根结点是,没办法 if (t->ch[0] != NULL && t->ch[0]->val == val) return t;
if (t->ch[1] != NULL && t->ch[1]->val == val) return t; if (val < t->val) return get(t->ch[0], val);
else return get(t->ch[1], val);
}*/
/*void update(Node *&t){
if (t == NULL) return;
update(t->ch[0]);
update(t->ch[1]);
t->size = 1;
if (t->ch[0] != NULL) t->size += t->ch[0]->size;
if (t->ch[1] != NULL) t->size += t->ch[1]->size;
}*/
void Delete(Node* &t,int x){
int d;
if (x == t->val) d = -;
else d = (x > t->val);
if (d == -){
Node *tmp = t;
if(t->ch[] == NULL){
t = t->ch[];
//poor.push(tmp);
delete tmp;
tmp = NULL;
}else if(t->ch[] == NULL){
t = t->ch[];
//poor.push(tmp);
delete tmp;
tmp = NULL;
}else{
int k = t->ch[]->fix > t->ch[]->fix ? : ;
//int k = 1;
rotate(t,k);
Delete(t->ch[k ^ ],x);
}
}else Delete(t->ch[d],x);
if (t!=NULL){
t->size = ;
if (t->ch[] != NULL) t->size += t->ch[]->size;
if (t->ch[] != NULL) t->size += t->ch[]->size;
}
}
/*void print(Node *t){
if (t == NULL) return;
print(t->ch[0]);
printf("%d ", t->val);
print(t->ch[1]);
}*/
}treap;
/*int Scan() {
int res = 0, ch, flag = 0;
if((ch = getchar()) == '-') //判断正负
flag = 1;
else if(ch >= '0' && ch <= '9') //得到完整的数
res = ch - '0';
while((ch = getchar()) >= '0' && ch <= '9' )
res = res * 10 + ch - '0';
return flag ? -res : res;
} */
int parent[N], n ,m;
int find(int x){return parent[x] < ? x : parent[x] = find(parent[x]);} void init(){
treap.init();
treap.root = NULL;
//memset(parent, -1, sizeof(parent));
scanf("%d%d", &n, &m);
for (int i = ; i <= n; i++) parent[i] = -;
//n = Scan();
//m = Scan();
//for (int i = 1; i <= n; i++) treap.insert(treap.root, 1);
}
void work(){
for (int i = ; i <= m; i++){
int t;
//t = Scan();
scanf("%d", &t);
if (t == ){
int x, y;
scanf("%d%d", &x, &y);
//x = Scan();y = Scan();
x = find(x);
y = find(y);
if (x == y) continue;
if (parent[x] < -) treap.Delete(treap.root, -parent[x]);
if (parent[y] < -) treap.Delete(treap.root, -parent[y]);
treap.insert(treap.root, -(parent[x] + parent[y]));
parent[y] += parent[x];
parent[x] = y;
}else{
int k;
scanf("%d", &k);
//k = Scan();i
if (treap.root == NULL || k > treap.root->size) {printf("1\n");continue;}
k = treap.root->size - k + ;
printf("%d\n", treap.kth(treap.root, k));
}
}
} int main(){
int T;
srand(time());
#ifdef LOCAL
freopen("data.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
init();
work();
//debug();
return ;
}

【POJ2985】【Treap + 并查集】The k-th Largest Group的更多相关文章

  1. POJ2985 The k-th Largest Group[树状数组求第k大值+并查集||treap+并查集]

    The k-th Largest Group Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8807   Accepted ...

  2. BZOJ 2733 [HNOI2012]永无乡(启发式合并+Treap+并查集)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2733 [题目大意] 给出n个点,每个点都有自己的重要度,现在有连边操作和查询操作, 查 ...

  3. 【BZOJ1604】[Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 Treap+并查集

    [BZOJ1604][Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 Description 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000) ...

  4. P1197 [JSOI2008]星球大战 并查集 反向

    题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治着整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过特殊的以太隧 ...

  5. Codeforces#514E(贪心,并查集)

    #include<bits/stdc++.h>using namespace std;long long w[100007],sum[100007];int fa[100007],degr ...

  6. 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 ...

  7. [poj-2985]The k-th Largest Group_Treap+并查集

    The k-th Largest Group poj-2985 题目大意:给你n只猫,有两种操作:1.将两只猫所在的小组合并.2.查询小组数第k大的小组的猫数. 注释:1<=n,m<=20 ...

  8. BZOJ 2733: [HNOI2012]永无乡(treap + 启发式合并 + 并查集)

    不难...treap + 启发式合并 + 并查集 搞搞就行了 --------------------------------------------------------------------- ...

  9. 【bzoj1604】[Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 旋转坐标系+并查集+Treap/STL-set

    题目描述 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发现她们已经结成了几个“群”.每只奶牛在吃草的时候有一个独一无二的位置坐标Xi,Yi(l≤Xi,Yi≤ ...

随机推荐

  1. 博弈论(SG函数):HNOI 2007 分裂游戏

    Description 聪聪和睿睿最近迷上了一款叫做分裂的游戏. 该游戏的规则试: 共有 n 个瓶子, 标号为 0,1,2.....n-1, 第 i 个瓶子中装有 p[i]颗巧克力豆,两个人轮流取豆子 ...

  2. snatch

    https://www.imququ.com/post/use-berserkjs-in-mac.html http://www.one-lab.net/ http://www.oschina.net ...

  3. m版页面判断安卓与ios系统

    安卓系统和ios系统,在做app里面嵌入m版时,有时候会发现,ios上面的那个电池状态栏不占位置,但是安卓的状态栏占位,所以需要区分系统样式单独处理一下! var sUserAgent=navigat ...

  4. winform 播放声音方式 分类: WinForm 2014-07-25 14:16 194人阅读 评论(0) 收藏

    声音文件folder.wav放置在bin目录下debug下 1.通过API调用 [c-sharp] view plaincopy using System.Runtime.InteropService ...

  5. Delphi中WebBrowser拦截网页Alert对话框消息(转)

    interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, O ...

  6. Delphi检查GetElementByID返回值的有效性

    Delphi 可以像JavaScript 脚本语言一样使用GetElementByID方法访问网页中指定ID的元素,一般要配合TWebBrowser组件使用.首先使用TWebBrowser浏览网页,然 ...

  7. java EE 学习

    http://blog.csdn.net/liushuijinger/article/category/1342030/1

  8. NSNotificationCenter消息机制的介绍

    转载自http://www.cnblogs.com/pengyingh/articles/2367374.html NSNotificationCenter的作用是专门提供程序中不同类之间的消息通讯而 ...

  9. [转] JavaScript 和事件

    与浏览器进行交互的时候浏览器就会触发各种事件.比如当我们打开某一个网页的时候,浏览器加载完成了这个网页,就会触发一个 load 事件:当我们点击页面中的某一个“地方”,浏览器就会在那个“地方”触发一个 ...

  10. 为什么我选择使用 Blocks(块)

    扯淡:到了新公司接手新框架之后,发现大量的使用Blocks,之前很多时候都是使用代理,突然面对这个陌生的语法,特地科普总结了一番. 什么是Blocks 一句话概括就是,带有局部变量的匿名函数(即不带名 ...