这题也能够用树状数组做,并且树状数组姿势更加优美。代码更加少,只是这个Treap树就是求第K大元素的专家……所以速度比較快。

这个也是从那本红书上拿的模板……自己找了资料百度了好久,才理解这个Treap主要的知识,要是自己写真的得写到什么时候啊!。。

然后输入的时候是写n-k+1反着找的,就是这里又浪费了好多时间debug。唉……

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <list>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#define PI acos(-1.0)
#define mem(a,b) memset(a,b,sizeof(a))
#define sca(a) scanf("%d",&a)
#define sc(a,b) scanf("%d%d",&a,&b)
#define pri(a) printf("%d\n",a)
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define MM 440004
#define MN 1008
#define INF 100000007
#define eps 1e-7
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
struct Treap
{
int root,treapCnt,key[MM],priority[MM],childs[MM][2],cnt[MM],size[MM];
Treap()
{
root=0;
treapCnt=1;
priority[0]=INF;
size[0]=0;
}
void update(int x)
{
size[x]=size[childs[x][0]]+cnt[x]+size[childs[x][1]];
}
void rotate(int &x,int t)
{
int y=childs[x][t];
childs[x][t]=childs[y][1-t];
childs[y][1-t]=x;
update(x);
update(y);
x=y;
}
void _insert(int &x,int k)
{
if(x)
{
if(key[x]==k) cnt[x]++;
else
{
int t=key[x]<k;
_insert(childs[x][t],k);
if(priority[childs[x][t]]<priority[x]) rotate(x,t);
}
}
else
{
x=treapCnt++;
key[x]=k;
cnt[x]=1;
priority[x]=rand();
childs[x][0]=childs[x][1]=0;
}
update(x);
}
void _erase(int &x,int k)
{
if(key[x]==k)
{
if(cnt[x]>1) cnt[x]--;
else
{
if(childs[x][0]==0&&childs[x][1]==0)
{
x=0;
return ;
}
int t=priority[childs[x][0]]>priority[childs[x][1]];
rotate(x,t);
_erase(x,k);
}
}
else _erase(childs[x][key[x]<k],k);
update(x);
}
int _getkth(int &x,int k)
{
if(k<=size[childs[x][0]]) return _getkth(childs[x][0],k);
k-=size[childs[x][0]]+cnt[x];
if(k<=0) return key[x];
return _getkth(childs[x][1],k);
}
void insert(int k)
{
_insert(root,k);
}
void erase(int k)
{
_erase(root,k);
}
int getkth(int k)
{
return _getkth(root,k);
}
}treap;
int f[MM],a[MM];
int find(int x)
{
return f[x]==x?x:f[x]=find(f[x]);
}
int main()
{
int n,m,i,k,x,y;
sc(n,m);
for(i=0;i<=n;i++) f[i]=i,a[i]=1; //初始每一个区间的元素都是1咯。自身嘛。
for(i=1;i<=n;i++) treap.insert(1);
for(i=1;i<=m;i++)
{
sca(k);
if(!k)
{
sc(x,y);
x=find(x),y=find(y);
if(x==y) continue;
f[y]=x;
treap.erase(a[x]); //先把这两个区间删除了
treap.erase(a[y]);
a[x]+=a[y]; //区间合并。元素相加
treap.insert(a[x]); //然后把合并的加到treap平衡树中
n--; //合并区间,总区间少1
}
else
{
sca(k);
pri(treap.getkth(n-k+1)); //反着找
}
}
return 0;
}

POJ 2985 Treap平衡树(求第k大的元素)的更多相关文章

  1. [LeetCode] Kth Largest Element in a Stream 数据流中的第K大的元素

    Design a class to find the kth largest element in a stream. Note that it is the kth largest element ...

  2. poj 2985 The k-th Largest Group 树状数组求第K大

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

  3. 《数据结构与算法分析:C语言描述》读书笔记------练习1.1 求第K大的数

    求一组N个数中的第k个最大者,设k=N/2. import java.util.Random; public class K_Max { /** * @param args */ //求第K大的数,保 ...

  4. 面试题:求第K大元素(topK)?

    一.引言二.普通算法算法A:算法B:三.较好算法算法C:算法D:四.总结 一.引言 ​ 这就是类似求Top(K)问题,什么意思呢?怎么在无序数组中找到第几(K)大元素?我们这里不考虑海量数据,能装入内 ...

  5. 快排法求第k大

    快排法求第k大,复杂度为O(n) import com.sun.media.sound.SoftTuning; import java.util.Arrays; import java.util.Ra ...

  6. HDU 5249 离线树状数组求第k大+离散化

    KPI Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  7. HDU 2639 01背包求第k大

    Bone Collector II Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  8. BZOJ2006:超级钢琴(ST表+堆求前K大区间和)

    Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度 ...

  9. ACM_求第k大元素(两次二分)

    求第k大 Time Limit: 6000/3000ms (Java/Others) Problem Description: 给定两个数组A和B,大小为N,M,每次从两个数组各取一个数相乘放入数组C ...

随机推荐

  1. python(6)-- 模块

    python模块: 定义:Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句. 作用:(a) 模块让你能够有逻辑地组织你 ...

  2. iOS之UITraitCollection

    UITraitCollection 为表征 size class 而生,用来区分设备.你可以在它身上获取到足以区分所有设备的特征. UITraitEnvironment 协议.UIContentCon ...

  3. 【HDOJ5972】Regular Number(Bitset,ShiftAnd)

    题意:给你N位数,接下来有N行,第i行先输入n,表示这个数的第i 位上可以在接下来的n个数中挑选,然后i 行再输n个数. 然后输入需要匹配的母串,让你输出母串中有多少个可行的N位子串. n<=1 ...

  4. 自动合并多个文件如js css等 可以增加效率

    原文发布时间为:2011-01-13 -- 来源于本人的百度文章 [由搬家工具导入] 原文地址:http://www.codeproject.com/KB/aspnet/HttpCombine.asp ...

  5. C#中Hashtable的用法 转

    原文发布时间为:2009-04-14 -- 来源于本人的百度文章 [由搬家工具导入] 一,哈希表(Hashtable)简述 在.NET Framework中,Hashtable是System.Coll ...

  6. java网络编程学习笔记(二):socket详解

    1.Socket有多种构造方法,大多数构造方法在构造的时候就指定了连接的主机和端口号.当客户端的构造方法与服务器连接的时候,可能需要等待一段时间,因为需要建立连接.默认情况下,Socket的构造方法会 ...

  7. Android开发基础(java)14

    Java语言与其他编程语言的最大不同之处在于:java有专门的异常处理机制,实现对各类异常情况进行有效控制. 一.基本概念:异常和错误的区别与联系: (1).定义形式不同:异常为exception:错 ...

  8. json手动解析详解

    项目中有时候仅仅需要一个或者多个字段时可以使用这种解析方式,省去创建实体类. 1.首先讲解下最基本的数据格式. 例如: String json="{'name':'小明','action': ...

  9. HTML5-contentEditable属性规定是否可编辑元素的内容

    contentEditable='true' :可以编辑 contentEditable='false' :不可以编辑

  10. Nowcoder Girl 参考题解【待写】

    [官方题解]:https://www.nowcoder.com/discuss/65411?toCommentId=1134823 [题目链接]:https://www.nowcoder.com/te ...