zoukankan      html  css  js  c++  java
  • hdu 4006 The kth great number SBT

    http://acm.hdu.edu.cn/showproblem.php?pid=4006

    直接用SBT中的get_max_Kth函数

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define LL long long
    const int maxn = 100010;
    #define ls T[x].l
    #define rs T[x].r
    #define lls T[ls].l
    #define lrs T[ls].r
    #define rls T[rs].l
    #define rrs T[rs].r
    struct SBT{
    	//左子树指针,右子树指针,大小,键值
    	int l,r,sz,key;
    	void init(){
    		l=r=key=0;
    		sz=1;
    	}
    }T[maxn];
    int root,tot; //根的位置以及节点个数
    //左旋转处理
    void l_rot(int &x){
    	int k=rs;
    	rs=T[k].l;
    	T[k].l=x;
    	T[k].sz=T[x].sz;
    	T[x].sz=T[ls].sz+T[rs].sz+1;
    	x=k;
    }
    //右旋转处理
    void r_rot(int &x){
    	int k=ls;
    	ls=T[k].r;
    	T[k].r=x;
    	T[k].sz=T[x].sz;
    	T[x].sz=T[ls].sz+T[rs].sz+1;
    	x=k;
    }
    //调整处理
    void maintain(int &x,bool flag){
    	if(flag){  //更新右子树
    		if(T[rrs].sz>T[ls].sz)
    			l_rot(x);
    		else if(T[rls].sz>T[ls].sz){
    			r_rot(rs);
    			l_rot(x);
    		}
    		else
    			return;
    	}
    	else{   //更新在左子树
    		if(T[lls].sz>T[rs].sz)
    			r_rot(x);
    		else if(T[lrs].sz>T[rs].sz){
    			l_rot(ls);
    			r_rot(x);
    		}
    		else
    			return;
    	}
    	//更新子树,然后再更新根,直到平衡为止
    	maintain(ls,false);
    	maintain(rs,true);
    	maintain(x,false);
    	maintain(x,true);
    }
    //插入新节点
    void insert(int &r,LL k){
    	if(r==0){
    		r=++tot;
    		T[r].init();
    		T[r].key=k;
    	}
    	else{
    		T[r].sz++;
    		if(k<T[r].key)
    			insert(T[r].l,k);
    		else
    			insert(T[r].r,k);
    		//插入后要调整,保证平衡
    		maintain(r,k>=T[r].key);
    	}
    }
    //删除结点,利用的是前驱替换
    int remove(int &r,int k){
    	int d_key;
    	if(!r)
    		return 0;
    	T[r].sz--;
    	//前者说明就是要删的节点,后两者说明不存在此节点
    	if(T[r].key==k||(T[r].l==0&&k<T[r].key)||(T[r].r==0&&k>T[r].key)){
    		d_key=T[r].key;
    		if(T[r].l&&T[r].r)
    			T[r].key=remove(T[r].l,k+1);
    		else
    			r=T[r].l+T[r].r;
    		return d_key;
    	}
    	else return remove(k<T[r].key?T[r].l:T[r].r,k);
    
    }
    int get_pre(int &x,int y,int k) {
        if(x == 0) return y;
        if(k > T[x].key) return get_pre(rs,x,k);
        else return get_pre(ls,y,k);
    }
    int get_next(int &x,int y,int k) {
        if(x == 0) return y;
        if(k < T[x].key) return get_next(ls,x,k);
        else return get_next(rs,y,k);
    }
    //取得第K大的数
    int get_max_Kth(int &x,int k){
    	int t=T[rs].sz+1;
    	if(t==k) return T[x].key;
    	if(t<k) return get_max_Kth(ls,k-t);
    	else return get_max_Kth(rs,k);
    }
    //取得第K小的数
    int get_min_Kth(int &x,int k){
        int t=T[ls].sz+1;
        if(t==k) return T[x].key;
        if(t<k) return get_min_Kth(rs,k-t);
        else return get_max_Kth(ls,k);
    }
    //查找树中是否存在元素
    int find(int &r,LL k){
    	if(!r) return 0;
    	if(T[r].key==k) return 1;
    	if(k<T[r].key) return find(T[r].l,k);
    	else return find(T[r].r,k);
    }
    //获得结点的名次
    int get_rank(int &x,int k) {
        if(k<T[x].key)
            return get_rank(ls,k);
        else if(k>T[x].key)
            return get_rank(rs,k)+T[ls].sz+1;
        else
            return T[ls].sz+1;
    }
    //排序
    void inorder(int &x) {
        if(x == 0) return;
        inorder(ls);
        printf("%d
    ",T[x].key);
        inorder(rs);
    }
    int n , k; char ch[11]; int p;
    int main() {
        while(~scanf("%d%d",&n,&k)) {
            root = tot = 0;
            while(n--) {
                scanf("%s" , ch);
                if(ch[0] == 'I') {
                    scanf("%d" , &p);
                    insert(root , p);
                }
                else {
                    int ans = get_max_Kth(root,k);
                    printf("%d
    " , ans);
                }
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    redolog switch会发生完全检查点还是增量检查点?
    4G牌照发放生变 专家谏言电信联通如何选择
    [财富]iPhone如何征服日本?
    审计中移动现多处问题或致地方高层落马
    诺基亚CEO:Lumia不会像安卓推廉价版机型
    菜鸟学JDBC(二)
    简易网页采集器的实现
    手Q与微信:最终结局将会是手足相残!
    做网站Http状态码详解
    PHP $_SERVER['HTTP_REFERER'] 获取前一页面的 URL 地址
  • 原文地址:https://www.cnblogs.com/tobec/p/3239485.html
Copyright © 2011-2022 走看看