zoukankan      html  css  js  c++  java
  • BZOJ 3224 普通平衡树

    3224: Tyvj 1728 普通平衡树

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 16841  Solved: 7319
    [Submit][Status][Discuss]

    Description

    您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
    1. 插入x数
    2. 删除x数(若有多个相同的数,因只删除一个)
    3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
    4. 查询排名为x的数
    5. 求x的前驱(前驱定义为小于x,且最大的数)
    6. 求x的后继(后继定义为大于x,且最小的数)

    Input

    第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

    Output

    对于操作3,4,5,6每行输出一个数,表示对应答案

    Sample Input

    10
    1 106465
    4 1
    1 317721
    1 460929
    1 644985
    1 84185
    1 89851
    6 81968
    1 492737
    5 493598

    Sample Output

    106465
    84185
    492737

    HINT

    1.n的数据范围:n<=100000

    2.每个数的数据范围:[-2e9,2e9]

    Source

    很裸的平衡树Treep,Splay都能写
    #include <bits/stdc++.h>
    using namespace std;
    char buf[1<<15],*fs,*ft;
    inline char getc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;}
    inline int read(){
    int x=0,f=1;  char ch=getc();
    while(!isdigit(ch))  {if(ch=='-')  f=-1;  ch=getc();}
    while(isdigit(ch))  {x=x*10+ch-'0';  ch=getc();}
    return x*f;
    }
    void put(int x){
    if(x==0){
    putchar('0');
    putchar('
    ');
    return;
    }
    if(x<0){
    putchar('-');
    x=-x;
    }
    int num=0;char ch[16];
    while(x) ch[++num]=x%10+'0',x/=10;
    while(num) putchar(ch[num--]);
    putchar('
    ');
    }
    const int MAXN=1e6+10;
    namespace zhangenming{
        struct node{
            int weight,sum,have,v;//weight表示节点的含有个数,sum表示所有子节点的和,have表示优先级,v表示节点的值
            int leftt,rightt;
        }T[MAXN];
        int n,tol=0,ans=0,root=0;
        inline void update(int root){
            T[root].sum=T[T[root].leftt].sum+T[T[root].rightt].sum+T[root].weight;
        }
        inline void left_rote(int &now){
            int tmp=T[now].rightt;
            T[tmp].sum=T[now].sum;
            T[now].rightt=T[tmp].leftt;
            T[tmp].leftt=now;
            update(now);now=tmp;
        }
        inline void right_rote(int &now){
            int tmp=T[now].leftt;
            T[tmp].sum=T[now].sum;
            T[now].leftt=T[tmp].rightt;
            T[tmp].rightt=now;
            update(now);now=tmp;
        }
        inline void insert(int x,int &root){
            if(root==0){
                tol++;root=tol;T[root].v=x;
                T[root].weight=T[root].sum=1;
                T[root].have=rand();return ;
            }
            T[root].sum++;
            if(T[root].v==x) {T[root].weight++;}
            else{
                if(x<T[root].v){
                    insert(x,T[root].leftt);
                    if(T[T[root].leftt].have>T[root].have) right_rote(root);
                }
                else{
                    insert(x,T[root].rightt);
                    if(T[T[root].rightt].have>T[root].have) left_rote(root);
                }
            }
        }
        inline void delte(int x,int &root){
            if(root==0) return ;
            if(x==T[root].v){
                if(T[root].weight>1){
                    T[root].weight--;T[root].sum--;return ;
                }
                if(T[root].leftt*T[root].rightt==0){
                    root=T[root].leftt+T[root].rightt;
                }
                else{
                    if(T[T[root].leftt].have<T[T[root].rightt].have){
                        right_rote(root);delte(x,root);
                    }
                    else{
                        left_rote(root);delte(x,root);
                    }
                }
            }
            else{
                if(T[root].v>x) {T[root].sum--;delte(x,T[root].leftt);}
                else {T[root].sum--;delte(x,T[root].rightt);}
            }
        }
        inline int getrank(int x,int root){
            if(root==0) return 0;
            if(T[root].v>x) return getrank(x,T[root].leftt);
            else{
                if(T[root].v<x) return T[T[root].leftt].sum+T[root].weight+getrank(x,T[root].rightt);
                else return T[T[root].leftt].sum+1;
            } 
        }
        inline int getnum(int x,int root){
            if(root==0) return 0;
                if(x>T[root].weight+T[T[root].leftt].sum){
                    return getnum(x-T[root].weight-T[T[root].leftt].sum,T[root].rightt);
                }
            else{
                if(x>T[T[root].leftt].sum){
                    return T[root].v;
                }
                else{
                    return getnum(x,T[root].leftt);
                }
            }
        }
        inline void getpre(int x,int root){
            if(root==0) return;
            if(T[root].v<x){
                ans=T[root].v;
                getpre(x,T[root].rightt);
            }
            else getpre(x,T[root].leftt);
        }
        inline void getnext(int x,int root){
            if(root==0) return;
            if(T[root].v>x){
                ans=T[root].v;
                getnext(x,T[root].leftt);
            }
            else getnext(x,T[root].rightt);
        }
        void init(){
            n=read();
            for(int i=1;i<=n;i++){
                int id=read();
                int xx=read();
                if(id==1) insert(xx,root);
                if(id==2) delte(xx,root);
                if(id==3) put(getrank(xx,root));
                if(id==4) put(getnum(xx,root));
                if(id==5) {getpre(xx,root);put(ans);}
                if(id==6) {getnext(xx,root);put(ans);}
            }
        }
    }
    int main(){
        //freopen("a.in","r",stdin);
        //freopen("a.out","w",stdout);
        using namespace zhangenming;
        init();
        return 0;
    }
    
  • 相关阅读:
    日程管理APP测试用例
    日程管理APP的测试计划和测试矩阵
    Bug report——仿网易新闻APP
    NABCD模拟实验
    5w1h

    小组作业
    code review
    Mutual review
    阅读思考
  • 原文地址:https://www.cnblogs.com/something-for-nothing/p/7881102.html
Copyright © 2011-2022 走看看