• BZOJ_3685_普通van Emde Boas树_权值线段树


    BZOJ_3685_普通van Emde Boas树_权值线段树

    Description

    设计数据结构支持:
    1 x  若x不存在,插入x
    2 x  若x存在,删除x
    3    输出当前最小值,若不存在输出-1
    4    输出当前最大值,若不存在输出-1
    5 x  输出x的前驱,若不存在输出-1
    6 x  输出x的后继,若不存在输出-1
    7 x  若x存在,输出1,否则输出-1

    Input

    第一行给出n,m 表示出现数的范围和操作个数
    接下来m行给出操作
    n<=10^6,m<=2*10^6,0<=x<n

    Output

    Sample Input

    10 11
    1 1
    1 2
    1 3
    7 1
    7 4
    2 1
    3
    2 3
    4
    5 3
    6 2

    Sample Output

    1
    -1
    2
    2
    2
    -1


    权值线段树写的,感觉不是很慢。

    唯一需要注意的是56操作时给出的x可能小于最小值/最大值,这时需要输出-1。

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define N 1000050
    #define ls p<<1
    #define rs p<<1|1
    #define maxn (n-1)
    inline char nc() {
        static char buf[100000],*p1,*p2;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    inline int rd() {
        register int x=0; register char s=nc();
        while(s<'0'||s>'9') s=nc();
        while(s>='0'&&s<='9') x=(x<<3)+(x<<1)+s-'0',s=nc();
        return x;
    }
    int t[N<<2],n,m,now;
    void insert(int l,int r,int x,int v,int p) {
        if(l==r) {
            if(v==0) {
                if(t[p]==0) now++;
                t[p]=1;
            }else {
                if(t[p]==1) now--;
                t[p]=0;
            }
            return ;
        }
        int mid=(l+r)>>1;
        if(x<=mid) insert(l,mid,x,v,ls);
        else insert(mid+1,r,x,v,rs);
        t[p]=t[ls]+t[rs];
    }
    int get_rank(int l,int r,int x,int p) {
        if(l==r) return 1;
        int mid=(l+r)>>1;
        if(x<=mid) return get_rank(l,mid,x,ls);
        else return get_rank(mid+1,r,x,rs)+t[ls];
    }
    int get_x(int l,int r,int k,int p) {
        if(l==r) return l;
        int mid=(l+r)>>1;
        if(k<=t[ls]) return get_x(l,mid,k,ls);
        else return get_x(mid+1,r,k-t[ls],rs);
    }
    int calcmin(int l,int r,int p) {
        if(l==r) return l;
        int mid=(l+r)>>1;
        if(t[ls]) return calcmin(l,mid,ls);
        else return calcmin(mid+1,r,rs);
    }
    int calcmax(int l,int r,int p) {
        if(l==r) return l;
        int mid=(l+r)>>1;
        if(t[rs]) return calcmax(mid+1,r,rs);
        else return calcmax(l,mid,ls);
    }
    int exist(int l,int r,int x,int p) {
        if(l==r) return t[p]?1:-1;
        int mid=(l+r)>>1;
        if(x<=mid) return exist(l,mid,x,ls);
        else return exist(mid+1,r,x,rs);
    }
    int main() {
        n=rd(); m=rd();
        int i,x,opt;
        for(i=1;i<=m;i++) {
            opt=rd();
            if(opt!=3&&opt!=4) x=rd(); 
            if(opt==1) {
                insert(0,maxn,x,0,1);
            }else if(opt==2) {
                insert(0,maxn,x,1,1);
            }else if(opt==3) {
                printf("%d
    ",now?calcmin(0,maxn,1):-1);
            }else if(opt==4) {
                printf("%d
    ",now?calcmax(0,maxn,1):-1);
            }else if(opt==5) {
                if(x<=calcmin(0,maxn,1)) puts("-1");
                else {
                    int k=get_rank(0,maxn,x,1)-1;
                    printf("%d
    ",get_x(0,maxn,k,1));
                }
            }else if(opt==6) {
                if(x>=calcmax(0,maxn,1)) puts("-1");
                else {
                    int k=get_rank(0,maxn,x+1,1);
                    printf("%d
    ",get_x(0,maxn,k,1));
                }
            }else {
                printf("%d
    ",exist(0,maxn,x,1));
            }
        }
    }
    
    
  • 相关阅读:
    I2C调试
    linux读取cpu温度
    看react全家桶+adtd有感
    react学习1(搭建脚手架,配置less,按需引入antd等)
    去掉console.log,正式环境不能有console.log
    Vue的minix
    数组去重我总结的最常用的方法,其他不常用就不写了
    inline-block bug解决方法
    vue中使用less/scss(这是2.0 3.0就不需要手动配置了只需要安装依赖就行了)
    Vue 调用微信扫一扫功能
  • 原文地址:https://www.cnblogs.com/suika/p/8998108.html
Copyright © 2020-2023  润新知