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

Posted fcwww

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n",now?calcmin(0,maxn,1):-1);
        }else if(opt==4) {
            printf("%d\n",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\n",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\n",get_x(0,maxn,k,1));
            }
        }else {
            printf("%d\n",exist(0,maxn,x,1));
        }
    }
}

 

以上是关于BZOJ_3685_普通van Emde Boas树_权值线段树的主要内容,如果未能解决你的问题,请参考以下文章

bzoj3685普通van Emde Boas树 权值zkw线段树

Van Emde Boas Tree

BZOJ_4765_普通计算姬_分块+dfs序+树状数组

BZOJ3224_普通平衡树_KEY

Vue中使用/deep/bug

bzoj 5056: OI游戏