zoukankan      html  css  js  c++  java
  • BZOJ 3224

    码了一发名次树,然后在remove和rank上GG了…… remove的话换了一种更保险的写法;而rank直接抄了Rujia Liu的代码…… 给Rj L跪了…

    // BZOJ 3224, Treap + Kth
    
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    using namespace std;
     
     #define read(x) scanf("%d", &x)
    
     struct Node {
     	Node *son[2]; // 0 <=> left, 1 <=> right
     	int p, v, s;
     	int cmp(int x) {
     		if (v==x) return -1;
     		return x<v ? 0 : 1;
     	}
     	void maintain() { s = son[1]->s + son[0]->s +1; }
     } *root;
    
     Node *null = new Node();
    
     void init() {
     	null->s = 0;
     	root = null;
     }
    
     void rotate(Node *&o, int d) {
     	Node *k = o->son[d^1];
     	o->son[d^1] = k->son[d];
     	k->son[d] = o;
     	o->maintain();
     	k->maintain();
     	o = k;
     } 
    
     // Movement 1
     void insert(Node *&o, int x) {
     	if (o==null) {
     		o = new Node();
     		o->v = x;
     		o->son[0] = o->son[1] = null;
     		o->p = rand();
     	}
     	else {
     		int d = (x < o->v ? 0 : 1); // 也可以直接用cmp函数,但后面要写得麻烦一点
     		insert(o->son[d], x);
     		if (o->son[d]->p > o->p) rotate(o, d^1);
     	}
     	o->maintain();
     }
    
     // Movement 2
     void remove(Node *&o, int x) {
     	if (o==null) return;
     	int d = o->cmp(x);
     	if (d==-1) {
     		Node *u = o;
     		if (o->son[0] != null && o->son[1] != null) {
     			int d2 = (o->son[0]->p > o->son[1]->p ? 1 : 0);
     			rotate(o, d2);
     			remove(o->son[d2], x);
     		}
     		else {
     			if (o->son[0] == null) o = o->son[1]; else o = o->son[0];
     			delete u;
     		}
     	} else remove(o->son[d], x);
     	if (o!=null) o->maintain();
     } 
    
     // Movement 3
     int get_rank(Node *o, int x) {
        if (o == null) return 1;
        if (x <= o->v) return get_rank(o->son[0], x);
        return get_rank(o->son[1], x) + (o->son[0] == null ? 0 : o->son[0]->s) + 1;
     }
    
     // Movement 4
     int kth(Node *o, int k) {
     	if (o==null || k<=0 || k > o->s) return 0; // 鲁棒语句:没有第k大的元素
     	int s = o->son[0]->s;
     	if (k==s+1) return o->v;
     	else if (k<=s) return kth(o->son[0], k);
     	else return kth(o->son[1], k-s-1);
     }
    
     // Movement 5
     int query_pre(int x) {  // 注意求前驱或后继时要忽略相同元素
     	Node *t = root;
     	int ret=0;
     	while (t != null) {
     		if (t->v < x) {
     			ret = t->v;
     			t = t->son[1];
     		} else t = t->son[0];
     	}
     	return ret;
     }
    
     // Movement 6
     int query_suf(int x) {
     	Node *t = root;
     	int ret=0;
     	while (t != null) {
     		if (t->v > x) {
     			ret = t->v;
     			t = t->son[0];
     		} else t = t->son[1];
     	}
     	return ret;
     }
    
    int main()
    {
    	int m, op, x;
        read(m);
        init();
        while (m--) {
        	read(op); read(x);
        	if (op==1) insert(root, x);
        	else if (op==2) remove(root, x);
        	else if (op==3) printf("%d
    ", get_rank(root, x));
        	else if (op==4) printf("%d
    ", kth(root, x));
        	else if (op==5) printf("%d
    ", query_pre(x));
        	else printf("%d
    ", query_suf(x));
        }
    
    	return 0;
    }
    
    
  • 相关阅读:
    js 练习,点击计算三个数的最大值,省级联动
    CSS 笔记
    CSS练习
    Html 学习笔记
    MySQL 执行计划详解
    别人家的元数据系统是怎么设计的
    深入浅出Dubbo RPC
    算法的时间复杂度和空间复杂度详解
    序列化 & 反序列化
    MySQL的四种隔离级别
  • 原文地址:https://www.cnblogs.com/yearwhk/p/5131535.html
Copyright © 2011-2022 走看看