POJ 2985 Treap平衡树(求第k大的元素)
这题也能够用树状数组做,并且树状数组姿势更加优美。代码更加少,只是这个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大的元素)的更多相关文章
- [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 ...
- poj 2985 The k-th Largest Group 树状数组求第K大
The k-th Largest Group Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 8353 Accepted ...
- 《数据结构与算法分析:C语言描述》读书笔记------练习1.1 求第K大的数
求一组N个数中的第k个最大者,设k=N/2. import java.util.Random; public class K_Max { /** * @param args */ //求第K大的数,保 ...
- 面试题:求第K大元素(topK)?
一.引言二.普通算法算法A:算法B:三.较好算法算法C:算法D:四.总结 一.引言 这就是类似求Top(K)问题,什么意思呢?怎么在无序数组中找到第几(K)大元素?我们这里不考虑海量数据,能装入内 ...
- 快排法求第k大
快排法求第k大,复杂度为O(n) import com.sun.media.sound.SoftTuning; import java.util.Arrays; import java.util.Ra ...
- HDU 5249 离线树状数组求第k大+离散化
KPI Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- HDU 2639 01背包求第k大
Bone Collector II Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- BZOJ2006:超级钢琴(ST表+堆求前K大区间和)
Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度 ...
- ACM_求第k大元素(两次二分)
求第k大 Time Limit: 6000/3000ms (Java/Others) Problem Description: 给定两个数组A和B,大小为N,M,每次从两个数组各取一个数相乘放入数组C ...
随机推荐
- 勒索病毒 -- “永恒之蓝”NSA 武器免疫工具
“永恒之蓝”NSA 武器免疫工具 针对 445 端口:445端口是一个毁誉参半的端口,他和139端口一起是IPC$入侵的主要通道.有了它我们可以在局域网中轻松访问各种共享文件夹或共享打印机,但也正是因 ...
- 关于javascript的"+="连接符
今天在读<javascript Dom 编程艺术>的时候,看到了自己感觉陌生的+=连接符(小白一枚,各位勿耻笑) "+="连接符,可以看成完成一次“加法和赋值”(或者“ ...
- Educational Codeforces Round 37 A B C D E F
A. water the garden Code #include <bits/stdc++.h> #define maxn 210 using namespace std; typede ...
- 《Linux命令行与shell脚本编程大全 第3版》Linux命令行---4
以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下: <Linux命令行与shell脚本 ...
- Linux Shell 文本处理工具集锦【转】
转自:http://www.cnblogs.com/me115/p/3427319.html 内容目录: find 文件查找 grep 文本搜索 xargs 命令行参数转换 sort 排序 uniq ...
- 转:C#制作ORM映射学习笔记一 自定义Attribute类
之前在做unity项目时发现只能用odbc连接数据库,感觉非常的麻烦,因为之前做web开发的时候用惯了ORM映射,所以我想在unity中也用一下ORM(虽然我知道出于性能的考虑这样做事不好的,不过自己 ...
- AC日记——文艺平衡树 洛谷 P3391
文艺平衡树 思路: splay翻转操作模板: 虚拟最左最右端点,然后每次都把l翻转到root,r+2翻转到root的右节点: 然后在r+2的左节点上打标记: 标记需要在旋转,rank,print时下放 ...
- 自做CA自签发SSL证书
一.把证书准备好.步骤与使用OpenSSL自签发服务器https证书所述大同小异.在这里再重复一次.1.制作CA证书:ca.key CA私钥: openssl genrsa -des3 -out ca ...
- Codeforces 743D Chloe and pleasant prizes(树型DP)
D. Chloe and pleasant prizes ...
- Machine Learning Done Wrong【转】
1. Take default loss function for granted Many practitioners train and pick the best model using the ...