zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    如何把SQLServer数据库从高版本降级到低版本
    关于如何利用Pocket CHM Pro制作帮助文档
    关于ASP.net TextBox控件的失去焦点后触发其它事件
    由window.history.back()引发的问题
    设置按钮不可用避免重复提交
    【转】一个高端.NET技术人才的2014年度总结
    Zabbix 各种报错信息和遇到的问题处理(持续总结更新~~~~~)
    ASP.NET调用Web Service
    ASP.NET导出bdf文件
    CS文件密码加密类
  • 原文地址:https://www.cnblogs.com/chanme/p/3906067.html
Copyright © 2011-2022 走看看