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. 【转】Ubuntu下搭建SVN环境-Apache

    原文网址:http://www.cnblogs.com/candle806/archive/2012/12/20/2826280.html 环境描述:ubuntu server 12.04  / sv ...

  2. WIA设备批量扫描

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  3. NIOS中双CPU系统的构建

    首先构建SOPC系统,先分别添加两个CPU,分别命名为CPU1和CPU2,设置如下图,其中CPU1运行VGA的乒乓游戏,CPU2运行音乐,这里为了简单,音乐用LED来表示. 这里CPU1选择是中等容量 ...

  4. HTML5 Canvas JavaScript库 Fabric.js 使用经验

    首先,表明我的态度:采用 Flash 才是最优方案,不建议使用 HTML 5 的 Canvas 做一些生产/工业级的网页应用. Flash的优势一是浏览器支持好,二是代码成熟稳定.而HTML5 的 C ...

  5. Eclipse的下载和安装

    下载 Android开发首选Eclipse for Android Developers版本,里面集成了ADT(Android Development Tools). 下载页面:http://www. ...

  6. HDU 3507 Print Article(DP+斜率优化)

     Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) ...

  7. [置顶] linux下让php支持mysql——寻找消失的mysql

       问题 最近我都在忙一个课件录制系统.这两天发现其中服务器端的一个更新数据库的php脚本运行有问题,一些本应该是系统自带函数却无法运行.于是我展开了调查... 服务器端是centos系统,其中ph ...

  8. XSS 简单理解之:AntiSamy

    AntiSamy介绍 OWASP是一个开源的.非盈利的全球性安全组织,致力于应用软件的安全研究.我们的使命是使应用软件更加安全,使企业和组织能够对应用安全风险作出更清晰的决策.目前OWASP全球拥有1 ...

  9. localstorage 初谈

    废话 : localStorage作为本地存储,比cookie大,可以看做一个小的服务器,几个api也可以看做增,删,查,找..... 设置 window.localStorage.setItem() ...

  10. SQL语法集锦三:合并列值与分拆列值

    本文转载http://www.cnblogs.com/lxblog/archive/2012/09/29/2708724.html 在SQL中分拆列值和合并列值老生常谈了,从网上搜刮了一下并记录下来, ...