bzoj 3685 普通van Emde Boas树(坑)

来源:互联网 发布:手机淘宝怎么追加差评 编辑:程序博客网 时间:2024/05/16 07:13

3685: 普通van Emde Boas树

Time Limit: 9 Sec Memory Limit: 128 MB
Submit: 1758 Solved: 563
[Submit][Status][Discuss]
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

HINT

Source

By Zky


【分析】

TLE的垃圾权值线段树。
空间本身就开不够,我还试水
又该自己挖下个坑233。


【代码】

//bzoj 3685 普通van Emde Boas树 #include<bits/stdc++.h>#define inf 1e9+7#define ll long long#define M(a) memset(a,0,sizeof a)#define fo(i,j,k) for(i=j;i<=k;i++)using namespace std;const int mxn=1000005;const int M=6000005;bool vis[M];int n,m,rt,tot;int ls[M],rs[M],mx[M],mn[M];inline int read(){    int x=0;char ch=getchar();    while(ch<'0' || ch>'9') ch=getchar();    while(ch>='0' && ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();    return x; }inline void update(int x){    vis[x]=vis[ls[x]]|vis[rs[x]];    mx[x]=max(mx[ls[x]],mx[rs[x]]);    mn[x]=min(mn[ls[x]],mn[rs[x]]);}inline void ins(int &x,int l,int r,int v){    if(!x) x=(++tot);    if(l==r)    {        mx[x]=mn[x]=v;        vis[x]=1;        return;    }    int mid=l+r>>1;    if(v<=mid) ins(ls[x],l,mid,v);    else ins(rs[x],mid+1,r,v);    update(x);}inline void del(int x,int l,int r,int v){    if(!x) return;    if(l==r)    {        mx[x]=-1,mn[x]=inf;        vis[x]=0;        return;    }    int mid=l+r>>1;    if(v<=mid) del(ls[x],l,mid,v);    else del(rs[x],mid+1,r,v);    update(x);}inline int rig(int x,int l,int r,int L,int R){    if(!x || L>R) return -1;    if(l==r && vis[x]) return l;    int mid=l+r>>1;    if(R<=mid) return rig(ls[x],l,mid,L,R);    else if(L>mid) return rig(rs[x],mid+1,r,L,R);    else    {        int tmp=rig(rs[x],mid+1,r,mid+1,R);        if(tmp!=-1) return tmp;        return rig(ls[x],l,mid,L,mid);    }}inline int lef(int x,int l,int r,int L,int R){    if(!x || L>R) return -1;    if(l==r && vis[x]) return l;    int mid=l+r>>1;    if(R<=mid) return lef(ls[x],l,mid,L,R);    else if(L>mid) return lef(rs[x],mid+1,r,L,R);    else    {        int tmp=lef(ls[x],l,mid,L,mid);        if(tmp!=-1) return tmp;        return lef(rs[x],mid+1,r,mid+1,R);    }}inline int yes(int x,int l,int r,int v){    if(!x) return -1;    if(l==r)    {        if(vis[x]) return 1;        else return -1;    }    int mid=l+r>>1;    if(v<=mid) return yes(ls[x],l,mid,v);    else return yes(rs[x],mid+1,r,v);}int main(){    int i,j,opt;    n=read(),m=read();    memset(mx,-1,sizeof mx);    memset(mn,0x3f,sizeof mn);    while(m--)    {        scanf("%d",&opt);        switch(opt)        {            case 1:ins(rt,0,n,read());break;            case 2:del(rt,0,n,read());break;            case 3:printf("%d\n",vis[rt]?mn[rt]:-1);break;            case 4:printf("%d\n",vis[rt]?mx[rt]:-1);break;            case 5:printf("%d\n",rig(rt,0,n,0,read()-1));break;            case 6:printf("%d\n",lef(rt,0,n,read()+1,n));break;            case 7:printf("%d\n",yes(rt,0,n,read()));break;        }    }    return 0;}/*31000001 01 2345 05 26 06 27 27 0*/