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

      

  • 相关阅读:
    技术人的思维修炼
    COMMIT在FORM中用法
    编译FORM 时出现错误 bad bind variable ’parameter.G_query_find‘
    描述性弹性域
    ORACLE EBS WebService推送报文例子 XML格式
    EBS值集,弹性域常用表
    ebs Form 表单个性化
    ebs界面颜色改变
    Oracle EBS数据定义移植工具:FNDLOAD
    在请求的参数中设置可选值列表为当前职责可访问的所有OU
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9335214.html
Copyright © 2011-2022 走看看