• 用树状数组实现的平衡树


    一、题目:

    洛谷模板

    二、思路:

    用树状数组实现的平衡树,实现起来很简单,但有很多细节需要考虑。

    维护一个权值树状数组,查排名时直接前缀和,前驱、后继都很简单。比较难的是已知排名求值,需要倍增。

    怎么能写二分呢?倍增比二分快几百倍。——LSH

    需要离散化,而细节很多,具体看代码。

    三、代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    
    using namespace std;
    inline int read(void){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return f*x;
    }
    
    const int maxn=100005;
    
    int n,b[maxn],cnt;
    
    struct Opt{
        int opt,x;
    }q[maxn];
    
    struct BIT{
        int tree[maxn];
        inline int lowbit(int x){return x&(-x);}
        inline void add(int p,int x){
            while(p<=cnt){
                tree[p]+=x;
                p+=lowbit(p);
            }
        }
        inline int rank(int p){
            int ans=1;--p;
            while(p>0){
                ans+=tree[p];
                p-=lowbit(p);
            }
            return ans;
        }
        
        inline int val(int rank){
            int ans=0,Cnt=0;
            for(register int i=20;i>=0;--i){
                ans+=(1<<i);
                if(ans>cnt||Cnt+tree[ans]>=rank)ans-=(1<<i);
                else Cnt+=tree[ans];
            }
            return ++ans;
        }
        inline int pre(int x){
            return val(rank(x)-1);
        }
        inline int nxt(int x){
            return val(rank(x+1));
        }
    }T;
    
    int main(){
        n=read();
        for(register int i=1;i<=n;++i){
            q[i].opt=read();
            q[i].x=read();
            if(q[i].opt!=4)b[++cnt]=q[i].x;
        }
        sort(b+1,b+cnt+1);
        cnt=unique(b+1,b+cnt+1)-b-1;
        for(register int i=1;i<=n;++i){
            if(q[i].opt!=4)q[i].x=lower_bound(b+1,b+cnt+1,q[i].x)-b;
        }
        for(register int i=1;i<=n;++i){
            switch(q[i].opt){
                case 1:
                    T.add(q[i].x,1);
                    break;
                case 2:
                    T.add(q[i].x,-1);
                    break;
                case 3:
                    cout<<T.rank(q[i].x)<<endl;
                    break;
                case 4:
                    // T.add(q[i].x,1);
                    cout<<b[T.val(q[i].x)]<<endl;
                    // T.add(q[i].x,-1);
                    break;
                case 5:
                    T.add(q[i].x,1);
                    cout<<b[T.pre(q[i].x)]<<endl;
                    T.add(q[i].x,-1);
                    break;
                case 6:
                    T.add(q[i].x,1);
                    cout<<b[T.nxt(q[i].x)]<<endl;
                    T.add(q[i].x,-1);
                    break;
            }
        }
        system("pause");
        return 0;
    }
    
  • 相关阅读:
    PHP与WCF第一次亲密接触
    PHP操作MongoDB
    如何用SVN进行个人版本管理
    【Android】还原“微信”apk中的“发现”和“我”两个模块
    使php支持mbstring库
    mysql 与 mysqli的区别
    nginx 配置正向 HTTP 代理服务器[转]
    正向代理与反向代理的区别【Nginx读书笔记】
    为什么要使用Nginx?
    【转】关于HTTP中文翻译的讨论
  • 原文地址:https://www.cnblogs.com/little-aztl/p/9746207.html
Copyright © 2020-2023  润新知