平衡树总是有用的,set由于过度封装没有办法实现找比x小的元素有多少个,这就显得很不方便了,所以封装了个Treap,万一以后用的着呢- -01

#pragma warning(disable:4996)
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <string>
#include <algorithm>
using namespace std; #define maxn 420000
const int inf = ~0U >> 1;
struct Node
{
int val, key, size; // value stored,priority key,size of total,number of current value
Node *ch[2];
Node(){
val = size = 0;
key = inf;
}
void upd(){
size = ch[0]->size + ch[1]->size + 1;
}
}; Node mem[maxn], *C = mem; Node *make(int v,Node *p){
C->ch[0] = C->ch[1] = p;
C->val = v; C->key = rand() - 1;
C->size = 1;
return C++;
} Node *make_null(){
C->ch[0] = C->ch[1] = 0;
C->val = 0; C->key = inf;
C->size = 0;
return C++;
} struct Treap
{
private:
Node *root, *null;
void rot(Node *&u, int d){
Node *v = u->ch[d];
u->ch[d] = v->ch[!d];
v->ch[!d] = u;
u->upd(); v->upd();
u = v;
}
void insert(Node *&u, int k){
if (u == null) u = make(k, null);
else if (u->val == k) return;
else{
int d = k > u->val;
Node *&v = u->ch[d];
insert(v, k);
if (v->key < u->key) rot(u, d);
}
u->upd();
}
void erase(Node *&u, int k){
if (u == null) return;
if (u->val == k){
int d = u->ch[1]->key < u->ch[0]->key;
if (u->ch[d] == null) {
u = null; return;
}
rot(u, d);
erase(u->ch[!d], k);
}
else erase(u->ch[k>u->val], k);
u->upd();
}
// left side has size of k
Node *select(Node *u, int k){
int r = u->ch[0]->size;
if (k == r)
return u;
if (k < r) return select(u->ch[0], k);
return select(u->ch[1], k - r - 1);
}
// return the number of elements smaller than x
int rank(Node *u, int x){
if (u == null) return 0;
int r = u->ch[0]->size;
if (x == u->val) return r;
else if (x < u->val) return rank(u->ch[0], x);
else return r + 1 + rank(u->ch[1], x);
}
bool find(Node *u, int x){
if (u == null) return false;
if (x == u->val) return true;
else return find(u->ch[x>u->val], x);
}
public:
Treap(){
null = make_null();
root = null;
}
void init(){
null = make_null();
root = null;
}
void insert(int x){
insert(root, x);
}
void erase(int x){
erase(root, x);
}
int select(int k){
if (k > root->size) return -inf;
else return select(root, k - 1)->val;
}
// return the element that is smaller than x
int rank(int x){
return rank(root, x);
}
// return whether x exist
bool find(int x){
return find(root, x);
}
}treap; int main()
{
int m; scanf("%d\n", &m);
char cmd;
int x;
while (m--){
scanf("%c %d\n", &cmd, &x);
if (cmd == 'I') treap.insert(x);
else if (cmd == 'D') treap.erase(x);
else if (cmd == 'K') {
int ans = treap.select(x);
if (ans == -inf) printf("invalid\n");
else printf("%d\n", ans);
}
else{
printf("%d\n", treap.rank(x));
}
}
return 0;
}

Treap模板的更多相关文章

  1. BZOJ 1588: Treap 模板

    1588: [HNOI2002]营业额统计 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 12171  Solved: 4352 Description ...

  2. [luogu3369]普通平衡树(treap模板)

    解题关键:treap模板保存. #include<cstdio> #include<cstring> #include<algorithm> #include< ...

  3. Treap 模板 poj1442&hdu4557

    原理可以看hihocoder上面的讲解,很清楚,不多说了. 模板抄lrj训练指南上面的. /** Treap 实现 名次树 功能: 1.找到排名为k的元素 2.值为x的元素的名次 初始化:Node* ...

  4. 平衡树Treap模板与原理

    这次我们来讲一讲Treap(splay以后再更) 平衡树是一种排序二叉树(或二叉搜索树),所以排序二叉树可以迅速地判断两个值的大小,当然操作肯定不止那么多(不然我们还学什么). 而平衡树在排序二叉树的 ...

  5. POJ1442-查询第K大-Treap模板题

    模板题,以后要学splay,大概看一下treap就好了. #include <cstdio> #include <algorithm> #include <cstring ...

  6. Treap 模板

    感觉平衡树也没有以前想的那么玄乎,(其实set超好用的),非旋式Treap挺好理解,和可并堆,二叉搜索树有很大联系 推荐博客:http://memphis.is-programmer.com/post ...

  7. 【Treap模板详细注释】BZOJ3224-普通平衡树

    模板题:D错因见注释 #include<iostream> #include<cstdio> #include<cstring> #include<algor ...

  8. 非旋treap模板

    bzoj3580 非旋转treap 在大神教导下发现split一段区间时先split右边再split左边比较好写 #include <cstdio> #include <cstdli ...

  9. codevs 4543 treap 模板

    type rec=record lc,rc,v,rnd,size,w,fa:longint; end; var n,root,tot,ans,opt,x,i,po:longint; tr:array[ ...

随机推荐

  1. NOJ1019-计算二叉树的高度和结点数

    输入 二叉树的先序遍历序列,用#代表空树或空子树. 输出 共五行 前三行依次输出先序.中序和后序遍历序列, 第四行输出二叉树的高度, 第五行依次输出二叉树总结点数目.叶子结点数目.度为1的结点数目. ...

  2. linux kernel同步机制的思考

    在学习内核同步机制的时候,书中介绍了同步方法:原子操作(atomic).自旋锁(spinlock).信号量(semaphore).互斥锁(mutex).完成变量(completion).大内核(BLK ...

  3. Mybatis 的日志管理

    Mybatis通过日志工厂提供日志信息,Mybatis内置的日志模版是log4j,commons.log,jdk log也可以通过slf4j简单日志模版结合log4j使用日志信息输出.具体选择哪个日志 ...

  4. 什么是O/R Mapping(ORM)

    ORM,即Object-Relationl Mapping,它的作用是在关系型数据库和对象之间作一个映射,这样,我们在具体的操作数据库的时候,就不需要再去和复杂的SQL语句打交道,只要像平时操作对象一 ...

  5. UITextField的常用属性,Delegate,重绘

        一  属性 UITextField * myTextField = [[UITextField alloc] initWithFrame:CGRectMake(50, 100, 200, 50 ...

  6. 微信支付.NET版开发总结(JS API),好多坑,适当精简。

    前2天,做一个手机网页的微信支付的项目,费了好些周折,记录一下.接下来,按照开发步骤,细数一下,我遇到的那些坑. [坑1]官方邮件中下载的demo只有PHP版本,其他版本没有给链接.可能让人误以为只有 ...

  7. params关键字

    每个C#函数都允许有个参数带params关键字,在调用的时候可以不给他传值,也可以给他传值,还可以给他传多个值 注意事项: ·一个函数中只能一个参数带params关键字:·带params关键字的参数必 ...

  8. 编译QT时出现lib/libQtGui.so: undefined reference to `ts_read_raw'的解决办法

    lib/libQtGui.so: undefined reference to `ts_read_raw' /lib/libQtGui.so: undefined reference to `ts_o ...

  9. Linux C 文件与目录4 将缓冲区数据写入磁盘

    将缓冲区数据写入磁盘 所谓缓冲区,是Linux系统对文件的一种处理方式.在对文件进行写操作时,并没有立即把数据写入到磁盘,而是把数据写入到缓冲区.如果需要把数据立即写入到磁盘,可以使用sync函数.用 ...

  10. 20145103 《Java程序设计》第2周学习总结

    20145103 <Java程序设计>第2周学习总结 教材学习内容总结 在第三章主要学习了Java语言中的类型及其变量主要类型为:整数(1字节的byte,2字节的short,4字节的int ...