1. 程式人生 > >BZOJ_3685_普通van Emde Boas樹_權值線段樹

BZOJ_3685_普通van Emde Boas樹_權值線段樹

true fread sam desc include 代碼 ID 權值線段樹 class

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樹_權值線段樹