• 平衡树


    • 老旧的treap(无rank无select)
      #include <iostream>
      #include <ctime>
      #include <cstdlib>
      using namespace std;
      
      #define NEW(d) new treap(d)
      
      struct treap {
      	treap* ch[2];
      	int key, s;
      	treap() : key(0), s(rand()) { ch[0] = ch[1] = NULL; }
      	treap(int d) : key(d), s(rand()) { ch[0] = ch[1] = NULL; }
      	bool operator< (const treap& a) { return s < a.s ? 1 : 0; }
      	int cmp(int d) {
      		if(key == d) return -1;
      		return key > d ? 0 : 1;
      	}
      }*root = NULL;
      
      typedef treap* tree;
      
      //左右旋,这里用的技巧是在lrj白书上看到的,旋转不多说,自己理解
      void rot(tree& rt, int d) {
      	tree k = rt-> ch[d^1]; rt-> ch[d^1] = k-> ch[d]; k-> ch[d] = rt; rt = k;
      }
      
      void insert(tree& rt, int d) {
      	if(rt == NULL) rt = NEW(d);
      	else {
      		int p = (rt-> key > d ? 0: 1);
      		insert(rt-> ch[p], d);
      		if(rt < rt-> ch[p]) rot(rt, p^1); //先插入再旋转
      	}
      }
      
      void del(tree& rt, int d) {
      	if(rt == NULL) return;
      	int c = rt-> cmp(d);
      	//如果找到节点
      	if(c == -1) {
      		//如果有左右子女
      		if(rt-> ch[0] != NULL && rt-> ch[1] != NULL) {
      			int p = (rt-> ch[1] < rt-> ch[0] ? 1 : 0);
      			rot(rt, p); del(rt-> ch[p], d);
      		}
      		//如果没有子女或只有一个子女
      		else {
      			tree t = rt;
      			if(rt-> ch[0] == NULL) rt = rt-> ch[1]; else rt = rt-> ch[0];
      			delete t;
      		}
      	}
      	//如果没找到节点
      	else
      		del(rt-> ch[c], d);
      }
      
      tree search(int d) {
      	tree ret = root;
      	while(ret != NULL && ret-> key != d) if(ret-> key > d) ret = ret-> ch[0]; else ret = ret-> ch[1];
      	return ret;
      }
      
      tree max(){
      	if(root == NULL) return NULL;
      	tree ret = root;
      	while(ret-> ch[1]) ret = ret-> ch[1];
      	return ret;
      }
      
      tree min(){
      	if(root == NULL) return NULL;
      	tree ret = root;
      	while(ret-> ch[0]) ret = ret-> ch[0];
      	return ret;
      }
      
      void out(string str) {
      	cout << str;
      }
      
      int main() {
      	out("1: insert
      2: del
      3: search
      4: max
      5: min
      ");
      	srand(time(NULL));
      	int c, t;
      	tree a;
      	while(cin >> c) {
      		switch(c) {
      		case 1: cin >> t;
      				insert(root, t);
      				break;
      		case 2: cin >> t;
      				del(root, t);
      				break;
      		case 3: cin >> t;
      				if(search(t) == NULL) out("Not here
      ");
      				else out("Is here!
      ");
      				break;
      		case 4: a = max();
      				if(a != NULL) cout << a-> key << endl;
      				else out("Warn!
      ");
      				break;
      		case 5: a = min();
      				if(a != NULL) cout << a-> key << endl;
      				else out("Warn!
      ");
      				break;
      		default:
      				break;
      		}
      	}
      	return 0;
      }
      
    • 指针工程版treap(判断数据合法性的,包括rank和select)
      #include <iostream>
      #include <ctime>
      #include <cstdlib>
      #include <string>
      using namespace std;
      
      #define R(t) t-> ch[1]
      #define L(t) t-> ch[0]
      #define C(t, c) t-> ch[c]
      #define S(t) t-> s
      #define W(t) t-> w
      #define K(t) t-> key
      #define PRE(t) R(t) = L(t) = null
      #define NEW new node
      
      struct Treap {
      	struct node {
      		int s, key, w;
      		node* ch[2];
      	};
      	typedef node* tree;
      	
      	tree root, null;
      	Treap() { null = NEW; PRE(null); root = null; }
      	
      	void pushup(tree t) {
      		S(t) = S(R(t)) + S(L(t)) + 1;
      	}
      	
      	void rot(tree& t, int d) {
      		tree k = C(t, d^1); 
      		C(t, d^1) = C(k, d); pushup(t);
      		C(k, d) = t; pushup(k);
      		t = k;
      	}
      	
      	void insert(tree& t, int k) {
      		if(t == null) { t = NEW; K(t) = k; W(t) = rand(); S(t) = 1; PRE(t); return; }
      		S(t)++;
      		int d = k >= K(t);
      		insert(C(t, d), k);
      		if(W(t) < W(C(t, d))) rot(t, d^1);
      	}
      	
      	void Del(tree& t, int k) {
      		S(t)--;
      		if(t == null) return;
      		if(k == K(t)) {
      			if(R(t) != null && L(t) != null) {
      				int d = W(R(t)) < W(L(t));
      				rot(t, d); Del(C(t, d), k);
      			}
      			else {
      				tree p = t;
      				if(R(t) == null) t = L(t); else t = R(t);
      				delete p;
      			}
      		}
      		else Del(C(t, k >= K(t)), k);
      	}
      	
      	tree select(tree t, int k) {
      		//第k小的数,如果要求第k大,可以在调用调也可以将select函数中的L(t)与R(t)调换即可
      		if(k > S(t) || k <= 0 || t == null) return null; //if k > S(root)
      		int s = S(L(t)) + 1;
      		if(k == s) return t;
      		else if(s > k) return select(L(t), k);
      		else return select(R(t), k-s);
      	}
      	
      	int Rank(tree t, int k) {
      		if(t == null) return 0; //if search() == null
      		int s = S(L(t)) + 1;
      		if(k == K(t)) return s;
      		if(k < K(t)) return Rank(L(t), k);
      		else return Rank(R(t), k)+s;
      	}
      	
      	void ins(int k) {
      		insert(root, k);
      	}
      	
      	void del(int k) {
      		Del(root, k);
      	}
      	
      	tree sel(int k) {
      		return select(root, k);
      	}
      	
      	int rank(int k) {
      		return Rank(root, k);
      	}
      	
      	tree search(int k) {
      		tree t = root;
      		while(t != null && k != K(t)) t = C(t, k >= K(t));
      		return t;
      	}
      
      	tree max() {
      		tree t = root, q = null;
      		while(t != null) q = t, t = R(t);
      		return q;
      	}
      	
      	tree min() {
      		tree t = root, q = null;
      		while(t != null) q = t, t = L(t);
      		return q;
      	}
      	
      }treap;
      
      void out(string str) {
      	cout << str;
      }
      
      int main() {
      	out("1: insert
      2: del
      3: search
      4: max
      5: min
      6: select
      7: rank
      ");
      	srand(time(NULL));
      	int c, t;
      	Treap::tree a, null = treap.null;
      	while(cin >> c) {
      		switch(c) {
      		case 1: cin >> t;
      				treap.ins(t);
      				break;
      		case 2: cin >> t;
      				treap.del(t);
      				break;
      		case 3: cin >> t;
      				if(treap.search(t) == null) out("Not here
      ");
      				else out("Is here!
      ");
      				break;
      		case 4: a = treap.max();
      				if(a != null) cout << K(a) << endl;
      				else out("Warn!
      ");
      				break;
      		case 5: a = treap.min();
      				if(a != null) cout << K(a) << endl;
      				else out("Warn!
      ");
      				break;
      		case 6: cin >> t;
      				a = treap.sel(t);
      				if(a != null) cout << K(a) << endl;
      				else out("Warn!
      ");
      				break;
      		case 7: cin >> t;
      				t = treap.rank(t);
      				if(t != 0) cout << t << endl;
      				else out("Warn!
      ");
      				break;
      		default:
      				break;
      		}
      	}
      	return 0;
      }
      
    • OI简短指针版treap模版
    #include 
    #include 
    #include 
    using namespace std;
    
    #define K(t) t-> key
    #define W(t) t-> w
    #define C(t, d) t-> ch[d]
    #define R(t) t-> ch[1]
    #define L(t) t-> ch[0]
    #define S(t) t-> s
    #define PRE(t) R(t) = L(t) = null
    #define NEW(k) new node(k)
    #define pushup(t) S(t) = S(L(t)) + S(R(t)) + 1
    
    struct Treap {
    	struct node {
    		int s, key, w;
    		node* ch[2];
    		node(int k = 0) : s(1), key(k), w(rand()) { ch[0] = ch[1] = NULL; }
    	};
    	typedef node* tree;
    	tree root, null;
    	Treap() { null = NEW(0); S(null) = 0; PRE(null); root = null; }
    	void rot(tree& t, int d) {
    		tree k = C(t, d^1);
    		C(t, d^1) = C(k, d); pushup(t);
    		C(k, d) = t; pushup(k);
    		t = k;
    	}
    	void insert(tree& t, int k) {
    		if(t == null) { t = NEW(k); PRE(t); return; }
    		S(t)++;
    		int p = k >= K(t);
    		insert(C(t, p), k);
    		if(W(t) < W(C(t, p))) rot(t, p^1);
    	}
    	void Del(tree& t, int k) {
    		S(t)--;
    		if(k == K(t)) {
    			if(L(t) != null && R(t) != null) {
    				int d = S(L(t)) > S(R(t));
    				rot(t, d); Del(C(t, d), k);
    			}
    			else {
    				tree p = t;
    				if(L(t) == null) t = R(t); else t = L(t);
    				delete p;
    			}
    		}
    		else Del(C(t, k >= K(t)), k);
    	}
    	int select(tree& t, int k) {
    		int s = S(L(t)) + 1;
    		if(s == k) return K(t);
    		if(s > k) return select(L(t), k);
    		else return select(R(t), k-s);
    	}
    	int Rank(tree& t, int k) {
    		int s = S(L(t)) + 1;
    		if(K(t) == k) return s;
    		if(K(t) > k) return Rank(L(t), k);
    		else return Rank(R(t), k)+s;
    	}
    	tree search(int k) {
    		tree t = root;
    		while(t != null && K(t) != k) t = C(t, k >= K(t));
    		return t;
    	}
    	int max() {
    		tree t = root;
    		while(R(t) != null) t = R(t);
    		return K(t);
    	}
    	int min() {
    		tree t = root;
    		while(L(t) != null) t = L(t);
    		return K(t);
    	}
    	
    	void ins(int k) {
    		insert(root, k);
    	}
    	void del(int k) {
    		Del(root, k);
    	}
    	int sel(int k) {
    		return select(root, k);
    	}
    	int rank(int k) {
    		return Rank(root, k);
    	}
    }T;
    
    int main() {
    	srand(time(NULL));
    	int c, t;
    	while(cin >> c) {
    		switch(c) {
    		case 1: cin >> t;
    				T.ins(t);
    				break;
    		case 2: cin >> t;
    				T.del(t);
    				break;
    		case 3: cin >> t;
    				if(T.search(t) == T.null) cout << "Not here
    ";
    				else cout << "Is here!
    ";
    				break;
    		case 4: cout << T.max() << endl;
    				break;
    		case 5: cout << T.min() << endl;
    				break;
    		case 6: cin >> t;
    				cout << T.sel(t) << endl;
    				break;
    		case 7: cin >> t;
    				cout << T.rank(t) << endl;
    				break;
    		default:
    				break;
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    avalon随笔
    ms-attr-data-real-gold="{{page_data[0].gold}}" 属性付真
    jQuery 快捷操作
    jQuery 属性操作
    jQuery 表单域选中选择器
    jQuery 层次选择器
    jQuery 基本选择器
    jQuery 基本使用
    jQuery 引入多个库文件冲突
    BOM window对象方法
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/3536845.html
Copyright © 2020-2023  润新知