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\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;

}

 

你可能感兴趣的:(模板)