zoukankan      html  css  js  c++  java
  • P3369 【模板】普通平衡树 平衡树

      

    题目描述

    您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:

    1. 插入xx数
    2. 删除xx数(若有多个相同的数,因只删除一个)
    3. 查询xx数的排名(排名定义为比当前数小的数的个数+1+1。若有多个相同的数,因输出最小的排名)
    4. 查询排名为xx的数
    5. xx的前驱(前驱定义为小于xx,且最大的数)
    6. xx的后继(后继定义为大于xx,且最小的数)

    输入格式

    第一行为nn,表示操作的个数,下面nn行每行有两个数optopt和xx,optopt表示操作的序号( 1 leq opt leq 61opt6 )

    输出格式

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

    输入输出样例

    输入 #1
    10
    1 106465
    4 1
    1 317721
    1 460929
    1 644985
    1 84185
    1 89851
    6 81968
    1 492737
    5 493598
    输出 #1
    106465
    84185
    492737


    维护权值的平衡树模板题
    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define ll long long
    #define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
    #define pb push_back
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    typedef pair<int,int>pii;
    //////////////////////////////////
    const int N=2e6+10;
    
    
    int son[N][2],fa[N],siz[N],cnt[N],val[N],ncnt,root;
    
    int chk(int x)
    {
        return son[fa[x]][1]==x;
    }
    
    void up(int x)
    {
        siz[x]=siz[son[x][0]]+siz[son[x][1]]+cnt[x];
    }
    
    void rotate(int x)
    {
        int y=fa[x],z=fa[y],k=chk(x),w=son[x][k^1];
        son[y][k]=w;fa[w]=y;
        son[z][chk(y)]=x;fa[x]=z;
        son[x][k^1]=y;fa[y]=x;
        up(x);up(y);
    }
    
    void splay(int x,int goal=0)
    {
        while(fa[x]!=goal)
        {
            int y=fa[x],z=fa[y];
            if(z!=goal)
            {
                if(chk(y)==chk(z))rotate(y);
                else rotate(x);
            }
            rotate(x);
        }
        if(!goal)root=x;
    }
    
    void find(int x)
    {
        if(!root)return ;
        int pos=root;
        while(son[pos][x>val[pos]]&&x!=val[pos])
        pos=son[pos][x>val[pos]];
    
        splay(pos);
    }
    
    
    void insert(int x)
    {
        int pos=root,p=0;
        while(pos&&val[pos]!=x)
        {
            p=pos;
            pos=son[pos][x>val[pos]];
        }
        if(pos)cnt[pos]++;
        else
        {
            pos=++ncnt;
            if(p)son[p][x>val[p]]=pos;
            son[pos][0]=son[pos][1]=0;
            val[pos]=x;fa[pos]=p;
            cnt[pos]=siz[pos]=1;
        }
        splay(pos);
    }
    
    int kth(int k)
    {
        int pos=root;
        while(1)
        {
            if(son[pos][0]&&siz[son[pos][0]]>=k)
            pos=son[pos][0];
            else if(k>siz[son[pos][0]]+cnt[pos])
            k-=siz[son[pos][0]]+cnt[pos],pos=son[pos][1];
            else {splay(pos);return pos;}
        }
    }
    
    
    int pre(int x)
    {
        find(x);
        if(val[root]<x)return root;
        int pos=son[root][0];
        while(son[pos][1])pos=son[pos][1];
        splay(pos);return pos;
    }
    
    int succ(int x)
    {
        find(x);
        if(val[root]>x)return root;
        int pos=son[root][1];
        while(son[pos][0])pos=son[pos][0];
        splay(pos);return pos;
    }
    
    void remove(int x)
    {
        int last=pre(x),nex=succ(x);
        splay(last);splay(nex,last);
        int pos=son[nex][0];
        if(cnt[pos]>1)
        {
            cnt[pos]--;splay(pos);
        }
        else son[nex][0]=0;
        up(root);up(nex);
    }
    
    void rank1(int x)
    {
        find(x);
        if(val[root]<=x) printf("%d
    ",siz[son[root][0]]);
        else if(val[root]>x) printf("%d
    ",siz[son[root][0]]+cnt[root]);
    
    
    int main()
    {
        int m;cin>>m; int a,b;
        insert(0x3f3f3f3f);
        insert(0xcfcfcfcf);
        while(m--)
        {
           scanf("%d%d",&a,&b);
            if(a==1)insert(b);
            if(a==2)remove(b);
            if(a==3)rank1(b);
            if(a==4)printf("%d
    ", val[kth(b+1)] );
            if(a==5)printf("%d
    ",val[pre(b)]);
            if(a==6)printf("%d
    ",val[succ(b)]);
        }
        return 0;
    }
    View Code




  • 相关阅读:
    什么是静态测试、动态测试、黑盒测试、白盒测试、α测试 β测试
    软件产品质量特性
    目前主要的测试用例设计方法是什么?
    软件的安全性应从哪几个方面去测试?
    软件配置管理的作用?软件配置包括什么?
    HDOJ1003(DP)
    HDOJ5650
    POJ1068(模拟)
    POJ2586(贪心)
    HDOJ1548(BFS)
  • 原文地址:https://www.cnblogs.com/bxd123/p/11297914.html
Copyright © 2011-2022 走看看