首页 > 代码库 > BZOJ 3685 普通van Emde Boas树 ZKW线段树

BZOJ 3685 普通van Emde Boas树 ZKW线段树

题目大意:维护一种数据结构,支持以下操作:

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

这题卡Treap,要写线段树

ZKW大法好啊 可惜我这个沙茶又写挂了……

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define M 2100100
using namespace std;
int n,m,q,tree[M];
void Add(int x)
{
	x+=q;
	if(tree[x])
		return ;
	for(;x;x>>=1)
		tree[x]++;
}
void Del(int x)
{
	x+=q;
	if(!tree[x])
		return ;
	for(;x;x>>=1)
		tree[x]--;
}
int Get_Min()
{
	int x;
	if(!tree[1])
		return 0;
	for(x=1;x<=q;x=tree[x<<1]?x<<1:x<<1|1);
	return x-q;
}
int Get_Max()
{
	int x;
	if(!tree[1])
		return 0;
	for(x=1;x<=q;x=tree[x<<1|1]?x<<1|1:x<<1);
	return x-q;
}
int Get_Pred(int x)
{
	for(x+=q;x^1;x>>=1)
		if(x&1&&tree[x>>1]>tree[x])
			break;
	if(x==1)
		return 0;
	for(x^=1;x<=q;x=tree[x<<1|1]?x<<1|1:x<<1);
	return x-q;
}
int Get_Secc(int x)
{
	for(x+=q;x^1;x>>=1)
		if(~x&1&&tree[x>>1]>tree[x])
			break;
	if(x==1)
		return 0;
	for(x^=1;x<=q;x=tree[x<<1]?x<<1:x<<1|1);
	return x-q;
}
int Exsist(int x)
{
	return tree[x+q]?1:-1;
}
int main()
{

	//freopen("3685.in","r",stdin);
	//freopen("3685.out","w",stdout);

	int i,p,x;
	cin>>n>>m;
	for(q=1;q<=n;q<<=1);
	for(i=1;i<=m;i++)
	{
		scanf("%d",&p);
		if(p==1)
		{
			scanf("%d",&x);
			Add(x+1);
		}
		if(p==2)
		{
			scanf("%d",&x);
			Del(x+1);
		}
		if(p==3)
			printf("%d\n",Get_Min()-1);
		if(p==4)
			printf("%d\n",Get_Max()-1);
		if(p==5)
		{
			scanf("%d",&x);
			printf("%d\n",Get_Pred(x+1)-1);
		}
		if(p==6)
		{
			scanf("%d",&x);
			printf("%d\n",Get_Secc(x+1)-1);
		}
		if(p==7)
		{
			scanf("%d",&x);
			printf("%d\n",Exsist(x+1));
		}
	}
}


BZOJ 3685 普通van Emde Boas树 ZKW线段树