zoukankan      html  css  js  c++  java
  • [洛谷P3369]【模板】普通平衡树

    题目大意:需要提供以下操作:

    1. 插入 $x$ 数
    2. 删除 $x$ 数(若有多个相同的数,应只删除一个)
    3. 查询 $x$ 数的排名(排名定义为比当前数小的数的个数 $+1$ 。若有多个相同的数,因输出最小的排名)
    4. 查询排名为 $x$ 的数
    5. 求 $x$ 的前驱(前驱定义为小于 $x$ ,且最大的数)
    6. 求 $x$ 的后继(后继定义为大于 $x$ ,且最小的数)

    题解:平衡树,treap

    卡点:

    C++ Code:

    #include <cstdio>
    #include <cstdlib>
    #define maxn 100050
    using namespace std;
    int n, op, x;
    struct treap {
    	int lc[maxn], rc[maxn], val[maxn], num[maxn], sz[maxn]; //val值,num堆值 
    	int root, idx;
    	int ta, tb, tmp, res;
    	int update(int p) {
    		sz[p] = sz[lc[p]] + sz[rc[p]] + 1;
    		return p;
    	}
    	int nw(int p) {
    		val[++idx] = p;
    		sz[idx] = 1;
    		num[idx] = rand();
    		return idx;
    	}
    	void split(int rt, int k, int &x, int &y) {
    		if (!rt) x = y = 0;
    		else {
    			if (val[rt] <= k) split(rc[rt], k, rc[rt], y), x = update(rt);
    			else split(lc[rt], k, x, lc[rt]), y = update(rt);
    		}
    	}
    	int merge(int x, int y) {
    		if (!x || !y) return x|y;
    		if (num[x] > num[y]) {rc[x] = merge(rc[x], y); return update(x);}
    		else {lc[y] = merge(x, lc[y]); return update(y);}
    	}
    	void insert(int p) {
    		if (!root) {
    			root = nw(p);
    		} else {
    			split(root, p, ta, tb);
    			root = merge(merge(ta, nw(p)), tb);
    		}
    	}
    	void erase(int p) {
    		split(root, p, ta, tb);
    		split(ta, p - 1, ta, tmp);
    		root = merge(ta, merge(merge(lc[tmp], rc[tmp]), tb));
    	}
    	int gtrnk(int p) {
    		split(root, p - 1, ta, tb);
    		res = sz[ta] + 1;
    		root = merge(ta, tb);
    		return res;
    	}
    	int gtk_th(int p, int k) {
    		while (true) {
    			if (sz[lc[p]] >= k) p = lc[p];
    			else
    				if (sz[lc[p]] + 1 == k) return val[p];
    				else k -= sz[lc[p]] + 1, p = rc[p];
    		}
    	}
    	int pre(int p) {
    		split(root, p - 1, ta, tb);
    		res = gtk_th(ta, sz[ta]);
    		root = merge(ta, tb);
    		return res;
    	}
    	int nxt(int p) {
    		split(root, p, ta, tb);
    		res = gtk_th(tb, 1);
    		root = merge(ta, tb);
    		return res;
    	}
    } T;
    
    int main() {
    	srand(20040826);
    	scanf("%d", &n);
    	while (n--) {
    		scanf("%d%d", &op, &x);
    		switch (op) {
    			case 1: {
    				T.insert(x);
    				break;
    			}
    			case 2: {
    				T.erase(x);
    				break;
    			}
    			case 3: {
    				printf("%d
    ", T.gtrnk(x));
    				break;
    			}
    			case 4: {
    				printf("%d
    ", T.gtk_th(T.root, x));
    				break;
    			}
    			case 5: {
    				printf("%d
    ", T.pre(x));
    				break;
    			}
    			case 6: {
    				printf("%d
    ", T.nxt(x));
    				break;
    			}
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    HDU 4069 Squiggly Sudoku
    SPOJ 1771 Yet Another NQueen Problem
    POJ 3469 Dual Core CPU
    CF 118E Bertown roads
    URAL 1664 Pipeline Transportation
    POJ 3076 Sudoku
    UVA 10330 Power Transmission
    HDU 1426 Sudoku Killer
    POJ 3074 Sudoku
    HDU 3315 My Brute
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9335214.html
Copyright © 2011-2022 走看看