Treap模板

平衡树总是有用的,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
", &m);
	char cmd;
	int x;
	while (m--){
		scanf("%c %d
", &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
");
			else printf("%d
", ans);
		}
		else{
			printf("%d
", treap.rank(x));
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/chanme/p/3906067.html