• HYSBZ 3224 Tyvj 1728 普通平衡树


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

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn=100000+10;
    const int Inf=1e9;
    typedef pair<int,int> D;
    struct Treap{
            int lch,rch;
            int data,sum,size;
            #define L(u) a[u].lch
            #define R(u) a[u].rch
    }a[maxn];
    int n,cnt,root;
    D Split(int,int);
    int Merge(int,int);
    void Pushup(int);
    void Insert(int);
    void Delte(int);
    int GetRank(int,int);
    int Find(int,int);
    int GetPre(int,int);
    int GetNext(int,int);
    int main(){
            // freopen("in.cpp","r",stdin);
            scanf("%d",&n);
            int op,x;
            for(int i=1;i<=n;i++){
                    scanf("%d%d",&op,&x);
                    if(op==1)Insert(x);
                    else if(op==2)Delte(x);
                    else if(op==3)printf("%d
    ",GetRank(root,x));
                    else if(op==4)printf("%d
    ",Find(root,x));
                    else if(op==5)printf("%d
    ",GetPre(root,x));
                    else printf("%d
    ",GetNext(root,x));
            }
            return 0;
    }
    void Pushup(int u){
            a[u].size=a[L(u)].size+a[R(u)].size+1;
    }
    D Split(int u,int k){
            if(u==0)return D(0,0);
            D y;
            int num=a[L(u)].size;
            if(num>=k){
                    y=Split(a[u].lch,k);
                    a[u].lch=y.second;
                    Pushup(u);
                    y.second=u;
            }else{
                    y=Split(a[u].rch,k-num-1);
                    a[u].rch=y.first;
                    Pushup(u);
                    y.first=u;
            }
            return y;
    }
    int Merge(int A,int B){
            if(A==0)return B;
            if(B==0)return A;
            if(rand()%(a[A].size+a[B].size)<a[A].size){
                    a[A].rch=Merge(a[A].rch,B);
                    Pushup(A);
                    return A;
            }else{
                    a[B].lch=Merge(A,a[B].lch);
                    Pushup(B);
                    return B;
            }
    }
    int GetRank(int u,int x){
            int ans=0,tmp=Inf;
            while(u){
                    if(x==a[u].data)tmp=min(tmp,ans+a[L(u)].size+1);
                    if(x>a[u].data)ans+=a[L(u)].size+1,u=a[u].rch;
                    else u=a[u].lch;
            }
            if(tmp==Inf)return ans;
            return tmp;
    }
    int Find(int u,int x){
            while(1){
                    if(a[L(u)].size==x-1)return a[u].data;
                    if(a[L(u)].size>x-1)u=a[u].lch;
                    else x=x-a[L(u)].size-1,u=a[u].rch;
            }
    }
    int GetPre(int u,int x){
            int ans=-Inf;
            while(u){
                    if(a[u].data<x)ans=max(ans,a[u].data),u=a[u].rch;
                    else u=a[u].lch;
            }
            return ans;
    }
    int GetNext(int u,int x){
            int ans=Inf;
            while(u){
                    if(a[u].data>x)ans=min(ans,a[u].data),u=a[u].lch;
                    else u=a[u].rch;
            }
            return ans;
    }
    void Insert(int x){
            int k=GetRank(root,x);
            D tmp=Split(root,k);
            a[++cnt].data=x;
            a[cnt].size=1;
            root=Merge(tmp.first,cnt);
            root=Merge(root,tmp.second);
    }
    void Delte(int x){
            int k=GetRank(root,x);
            D t1=Split(root,k);
            D t2=Split(t1.first,k-1);
            root=Merge(t2.first,t1.second);
    }

  • 相关阅读:
    POJ-3254 + POJ-1185 状压DP入门题
    POJ-3667 线段树区间合并入门题
    HDU-4507 数位DP 记录一个毒瘤错误orz
    HDU-4734 F(x)数位dp
    HDU-3709 Balanced Number 数位dp+枚举
    分块入门 LibreOJ分块九题
    HDU-4389 X mod f(x) && 2018上海大都会邀请赛J 数位dp
    HDU-3038 How Many Answers Are Wrong (带权并查集)
    Codeforces 608B Hamming Distance Sum (前缀和)
    (二十六 )数据库:水平切分,数据库秒级扩容!
  • 原文地址:https://www.cnblogs.com/holy-unicorn/p/9510106.html
Copyright © 2020-2023  润新知