• Bzoj 3224 普通平衡树


    地址 https://ac.nowcoder.com/acm/contest/1036/A

    您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
    
    插入数值 x。
    删除数值 x(若有多个相同的数,应只删除一个)。
    查询数值 x 的排名(若有多个相同的数,应输出最小的排名)。
    查询排名为 x 的数值。
    求数值 x 的前驱(前驱定义为小于 x 的最大的数)。
    求数值 x 的后继(后继定义为大于 x 的最小的数)。
    注意: 数据保证查询的结果一定存在。
    
    输入格式
    第一行为 n,表示操作的个数。
    
    接下来 n 行每行有两个数 opt 和 x,opt 表示操作的序号(1≤opt≤6)。
    
    输出格式
    对于操作 3,4,5,6 每行输出一个数,表示对应答案。
    
    数据范围
    1≤n≤100000,所有数均在 −107 到 107 内。
    
    输入样例:
    8
    1 10
    1 20
    1 30
    3 20
    4 2
    2 10
    5 25
    6 -1
    输出样例:
    2
    20
    20
    20
    

    解答
    treap树的模板题目 这里将模板记录

    // 111235.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
    //
    
    #include <iostream>
    #include <algorithm>
    
    using  namespace std;
    
    const int N = 100010; 
    int INF = 1e8;
    
    int n;
    struct Node {
    	int l, r;
    	int key, val;
    	int cnt, size;
    }tr[N];
    int root, idx;
    
    void pushup(int p) {
    	tr[p].size = tr[tr[p].l].size +
    			tr[tr[p].r].size + tr[p].cnt;
    
    }
    
    int get_node(int key) {
    	tr[++idx].key = key;
    	tr[idx].val = rand();
    	tr[idx].cnt = tr[idx].size = 1;
    	return idx;
    }
    
    void build() {
    	get_node(-INF);
    	get_node(INF);
    	root = 1;
    	tr[1].r = 2;
    	pushup(root);
    }
    
    //右旋
    void zig(int &p) {
    	int q = tr[p].l;
    	tr[p].l = tr[q].r, tr[q].r = p; p = q;
    	pushup(tr[p].r);
    	pushup(p);
    }
    
    //左旋
    void zag(int& p) {
    	int q = tr[p].r;
    	tr[p].r = tr[q].l;
    	tr[q].l = p; p = q;
    	pushup(tr[p].l); pushup(p);
    }
    
    void insert(int &p,int key) {
    	if (!p) p = get_node(key);
    	else if (tr[p].key == key) tr[p].cnt++;
    	else if (tr[p].key > key) {
    		insert(tr[p].l, key);
    		if (tr[tr[p].l].val > tr[p].val) zig(p);
    	}
    	else {
    		insert(tr[p].r,key);
    		if (tr[tr[p].r].val > tr[p].val) zag(p);
    	}
    	pushup(p);
    }
    
    void remove(int &p, int key) {
    	if (!p) return;
    	if (tr[p].key == key) {
    		if (tr[p].cnt > 1) tr[p].cnt--;
    		else if (tr[p].l || tr[p].r) {
    			if (!tr[p].r || tr[tr[p].l].val > tr[tr[p].r].val) {
    				zig(p);
    				remove(tr[p].r, key);
    			}
    			else {
    				zag(p);
    				remove(tr[p].l, key);
    			}
    		}
    		else p = 0;
    	}
    	else if (tr[p].key > key) {
    		remove(tr[p].l, key);
    	}
    	else {
    		remove(tr[p].r, key);
    	}
    	pushup(p);
    }
    
    int get_rank_by_key(int& p, int key) {
    	if (!p) return 0;
    	if (tr[p].key == key) return tr[tr[p].l].size + 1;
    	if (tr[p].key > key) return get_rank_by_key(tr[p].l,key);
    	return tr[tr[p].l].size + tr[p].cnt + get_rank_by_key(tr[p].r,key);
    	return 0;
    }
    
    
    int get_key_by_rank(int& p, int rank) {
    	if (!p) return INF;
    	if (tr[tr[p].l].size >= rank) return get_key_by_rank(tr[p].l,rank);
    	if (tr[tr[p].l].size + tr[p].cnt >= rank) return tr[p].key;
    	return get_key_by_rank(tr[p].r,rank-tr[tr[p].l].size-tr[p].cnt);
    	return 0;
    }
    
    
    
    
    int get_prev(int& p, int key) {
    	if (!p)  return -INF;
    	if (tr[p].key >= key)return get_prev(tr[p].l,key);
    	return max(tr[p].key,get_prev(tr[p].r,key));
    
    	return 0;
    }
    
    
    
    int get_next(int& p, int key) {
    	if (!p) return INF;
    	if (tr[p].key <= key) return get_next(tr[p].r, key);
    	return min(tr[p].key, get_next(tr[p].l,key));
    
    	return 0;
    }
    
    
    
    int main()
    {
    	build();
    
    	cin >> n;
    	while (n--) {
    		int opt, x;
    		cin >> opt>>x;
    		if (opt == 1) {
    			insert(root,x);
    		}
    		else if (opt == 2) {
    			remove(root,x);
    		}
    		else if (opt == 3) {
    			cout << get_rank_by_key(root,x)-1<<endl;
    		}
    		else if (opt == 4) {
    			cout << get_key_by_rank(root,x+1)<< endl;
    		}
    		else if (opt == 5) {
    			cout << get_prev(root, x) <<  endl;
    		}
    		else if (opt == 6) {
    			cout << get_next(root, x) << endl;
    		}
    	}
    
    
    	return 0;
    }
    

    我的视频题解空间

    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    UVA
    [CQOI2018] 社交网络
    UVA
    51nod 1314 定位系统
    51nod 1211 数独
    51nod 1392 装盒子
    51nod1253 Kundu and Tree
    51nod1313 完美串
    51nod1039 x^3 mod p
    51nod1369 无穷印章
  • 原文地址:https://www.cnblogs.com/itdef/p/15450434.html
Copyright © 2020-2023  润新知