您的位置:首页 > 其它

【权值分块】bzoj3685 普通van Emde Boas树

2014-11-14 16:39 387 查看
权值分块,虽然渐进复杂度不忍直视,但其极小的常数使得实际运行起来比平衡树快,大多数情况和递归版权值线段树差不多,有时甚至更快。但是被zkw线段树完虐。

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define N 1000001
int maxv,minv=2147483647;
int n,op,a,m,ma
,en,l[1100],r[1100],sumv[1100],sz,sum,num
;
bool b
;
void makeblock()
{
sz=sqrt(n); if(!sz) sz=1; r[0]=-1;
for(sum=1;sum*sz<n-1;sum++)
{
l[sum]=r[sum-1]+1;
r[sum]=sz*sum-1;
for(int i=l[sum];i<=r[sum];i++) num[i]=sum;
}
l[sum]=r[sum-1]+1;
r[sum]=n-1;
for(int i=l[sum];i<=r[sum];i++) num[i]=sum;
}
inline void Insert(const int &x){if(b[x]) return; b[x]=1; sumv[num[x]]++;}
inline void Delete(const int &x){if(!b[x]) return; b[x]=0; sumv[num[x]]--;}
inline int Next(const int &x)
{
for(int i=x+1;i<=r[num[x]];i++) if(b[i]) return i;
for(int i=num[x]+1;i<=sum;i++) if(sumv[i])
for(int j=l[i];j<=r[i];j++)
if(b[j]) return j;
return -1;
}
inline int Pre(const int &x)
{
for(int i=x-1;i>=l[num[x]];i--) if(b[i]) return i;
for(int i=num[x]-1;i>=1;i--) if(sumv[i])
for(int j=r[i];j>=l[i];j--)
if(b[j]) return j;
return -1;
}
inline int Min()
{
for(int i=1;i<=sum;i++) if(sumv[i])
for(int j=l[i];j<=r[i];j++) if(b[j]) return j;
return -1;
}
inline int Max()
{
for(int i=sum;i>=1;i--) if(sumv[i])
for(int j=r[i];j>=l[i];j--) if(b[j]) return j;
return -1;
}
int main()
{
scanf("%d%d",&n,&m);
makeblock();
for(int i=1;i<=m;i++)
{
scanf("%d",&op); if(op!=3&&op!=4) scanf("%d",&a);
if(op==1) Insert(a);
else if(op==2) Delete(a);
else if(op==3) printf("%d\n",Min());
else if(op==4) printf("%d\n",Max());
else if(op==5) printf("%d\n",Pre(a));
else if(op==6) printf("%d\n",Next(a));
else printf("%d\n",b[a] ? 1 : -1);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: