Treap模板

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

#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模板,布布扣,bubuko.com

时间: 2024-08-11 05:44:34

Treap模板的相关文章

BZOJ 1588: Treap 模板

1588: [HNOI2002]营业额统计 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 12171  Solved: 4352 Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额.分析营业情况是一项相当复杂的工作.由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波

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

模板题:D错因见注释 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 const int INF=0x7fffffff; 8 struct treap 9 { 10 treap* lson; 11 treap* rson; 12 int key;/

Treap 模板 poj1442&amp;hdu4557

原理可以看hihocoder上面的讲解,很清楚,不多说了. 模板抄lrj训练指南上面的. /** Treap 实现 名次树 功能: 1.找到排名为k的元素 2.值为x的元素的名次 初始化:Node* root = NULL; */ #include <cstdlib> #include <cstdio> #include <cstring> #include <vector> using namespace std; struct Node { Node *

人生第一发treap模板

bzoj3224 模板参(chao)考(xi)了hzwer神犇,ORZ //treap #include<cstdio> #include<iostream> #include<cstdlib> using namespace std; struct node { int l,r,v,w,rnd,size; }; node tr[100011]; int num=0,root=0,size=0; void update(int k) { tr[k].size=tr[tr

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

模板题,以后要学splay,大概看一下treap就好了. 1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 5 using namespace std; 6 7 const int maxn = 3e5+10; 8 int num[maxn],st[maxn]; 9 10 struct Treap{ 11 int size; 12 int key,fix; 13 Treap *ch[2];

BZOJ1208: [HNOI2004]宠物收养所 平衡树 Treap 模板题

Description 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被 主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希 望领养的宠物的特点值a(a是一个正整数,a<2^31),而他也给每个处在收养所的宠物一个特点值.这样他就能够很方便的处理整个领养宠物的过程 了,宠物收养所总是会有两种情况发生:被遗弃的宠物过多或者是想要收养宠物的人太多,而宠物太少. 1. 被遗弃的宠物过多时,假若到来一个

POJ 3481 Double Queue(Treap模板题)

Double Queue Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15786   Accepted: 6998 Description The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest, equipped with a modern computing environment provid

[临时]NULL00 Treap模板 已去除宏

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <time.h> 4 5 struct node_t 6 { 7 node_t* left;//左节点 8 node_t* right;//右节点 9 int priority;//优先级 10 int key;//存储的关键字 11 }; 12 13 struct treap_t 14 { 15 node_t* root; 16 }; 17 18 //左旋转 1

BZOJ 3224 普通平衡树(treap模板题)

3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 14301  Solved: 6208 [Submit][Status][Discuss] Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 1. 插入x数 2. 删除x数(若有多个相同的数,因只删除一个) 3. 查询x数的排名(若有多个相同的数,因输出最小的排名) 4. 查询排名为x的数 5. 求x的前