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

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

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cmath>
 4 using namespace std;
 5 #define N 1000001
 6 int maxv,minv=2147483647;
 7 int n,op,a,m,ma[N],en,l[1100],r[1100],sumv[1100],sz,sum,num[N],Num,CH[12];
 8 bool b[N];
 9 inline void R(int &x){
10     char c=0;int f=1;
11     for(;c<‘0‘||c>‘9‘;c=getchar())if(c==‘-‘)f=-1;
12     for(x=0;c>=‘0‘&&c<=‘9‘;c=getchar())(x*=10)+=(c-‘0‘);
13     x*=f;
14 }
15 inline void P(int x)
16 {
17     if(!x){putchar(‘0‘);puts("");return;}
18     if(x<0){putchar(‘-‘);x=-x;}Num=0;
19     while(x>0)CH[++Num]=x%10,x/=10;
20     while(Num)putchar(CH[Num--]+48);puts("");
21 }
22 void makeblock()
23 {
24     sz=sqrt(n); if(!sz) sz=1; r[0]=-1;
25     for(sum=1;sum*sz<n-1;sum++)
26       {
27           l[sum]=r[sum-1]+1;
28           r[sum]=sz*sum-1;
29           for(int i=l[sum];i<=r[sum];i++) num[i]=sum;
30       }
31     l[sum]=r[sum-1]+1;
32     r[sum]=n-1;
33     for(int i=l[sum];i<=r[sum];i++) num[i]=sum;
34 }
35 inline void Insert(const int &x){if(b[x]) return; b[x]=1; sumv[num[x]]++;}
36 inline void Delete(const int &x){if(!b[x]) return; b[x]=0; sumv[num[x]]--;}
37 inline int Next(const int &x)
38 {
39     for(int i=x+1;i<=r[num[x]];i++) if(b[i]) return i;
40     for(int i=num[x]+1;i<=sum;i++) if(sumv[i])
41       for(int j=l[i];j<=r[i];j++)
42         if(b[j]) return j;
43     return -1;
44 }
45 inline int Pre(const int &x)
46 {
47     for(int i=x-1;i>=l[num[x]];i--) if(b[i]) return i;
48     for(int i=num[x]-1;i>=1;i--) if(sumv[i])
49       for(int j=r[i];j>=l[i];j--)
50         if(b[j]) return j;
51     return -1;
52 }
53 inline int Min()
54 {
55     for(int i=1;i<=sum;i++) if(sumv[i])
56     for(int j=l[i];j<=r[i];j++) if(b[j]) return j;
57     return -1;
58 }
59 inline int Max()
60 {
61     for(int i=sum;i>=1;i--) if(sumv[i])
62     for(int j=r[i];j>=l[i];j--) if(b[j]) return j;
63     return -1;
64 }
65 int main()
66 {
67     scanf("%d%d",&n,&m);
68     makeblock();
69     for(int i=1;i<=m;i++)
70       {
71           scanf("%d",&op); if(op!=3&&op!=4) scanf("%d",&a);
72           if(op==1) Insert(a);
73           else if(op==2) Delete(a);
74           else if(op==3) printf("%d\n",Min());
75           else if(op==4) printf("%d\n",Max());
76           else if(op==5) printf("%d\n",Pre(a));
77           else if(op==6) printf("%d\n",Next(a));
78           else printf("%d\n",b[a] ? 1 : -1);
79       }
80     return 0;
81 }
时间: 2024-10-21 09:45:47

【权值分块】bzoj3685 普通van Emde Boas树的相关文章

bzoj3685普通van Emde Boas树 线段树

3685: 普通van Emde Boas树 Time Limit: 9 Sec  Memory Limit: 128 MBSubmit: 1932  Solved: 626[Submit][Status][Discuss] Description 设计数据结构支持:1 x  若x不存在,插入x2 x  若x存在,删除x3    输出当前最小值,若不存在输出-14    输出当前最大值,若不存在输出-15 x  输出x的前驱,若不存在输出-16 x  输出x的后继,若不存在输出-17 x  若x

bzoj3685: 普通van Emde Boas树 set+读入优化

显然这题的所有操作都可以用set,但是直接用set肯定要T,考虑到读入量较大,使用fread读入优化,就可以卡过去了. #include<bits/stdc++.h> using namespace std; void read(int& x){ const int k=1600000; static char v, u[k],*s=u,*t=u; x=0; while(isspace(v=s==t &&u==(t=u+fread(s=u, 1,k,stdin))?-1

BZOJ 3685: 普通van Emde Boas树( 线段树 )

建颗权值线段树就行了...连离散化都不用... 没加读入优化就TLE, 加了就A掉了...而且还快了接近1/4.... ------------------------------------------------------------------------------------------ #include<bits/stdc++.h> #define rep(i, n) for(int i = 0; i < n; i++) #define clr(x, c) memset(x

bzoj 3685: 普通van Emde Boas树

3685: 普通van Emde Boas树 Description 设计数据结构支持:1 x  若x不存在,插入x2 x  若x存在,删除x3    输出当前最小值,若不存在输出-14    输出当前最大值,若不存在输出-15 x  输出x的前驱,若不存在输出-16 x  输出x的后继,若不存在输出-17 x  若x存在,输出1,否则输出-1 Input 第一行给出n,m 表示出现数的范围和操作个数接下来m行给出操作n<=10^6,m<=2*10^6,0<=x<n Sample

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

原文地址:http://www.cnblogs.com/GXZlegend/p/6809743.html 题目描述 设计数据结构支持:1 x  若x不存在,插入x2 x  若x存在,删除x3    输出当前最小值,若不存在输出-14    输出当前最大值,若不存在输出-15 x  输出x的前驱,若不存在输出-16 x  输出x的后继,若不存在输出-17 x  若x存在,输出1,否则输出-1 输入 第一行给出n,m 表示出现数的范围和操作个数接下来m行给出操作n<=10^6,m<=2*10^6,

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 1

[CLRS][CH 20] van Emde Boas 树

vEB树简介 当关键字是有界范围内整数时,能够避免排序的 Ω(nlgn) 的下界限制.vEB树支持动态集合上运行时间为 O(lglgn) 的操作:Search, Insert, Delete, Min, Max, Successor 和 Predecessor. 接下来,用 n 表示集合中当前元素的个数,用 u 表示元素的可能取值范围.这样vEB树的操作运行时间就为 O(lglgu). 太难了...放弃先......

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<i

Van Emde Boas Tree

van Emde Boas trees 支持所有优先级优先级队列的操作,并且巧妙的是它对于SEARCH, INSERT,DELETE,MINIMUM,MAXMUN,SUCCESSOR,和PREDECESSOR这些操作的支持都在最坏复 杂度O(lglgn)之内.不过有些限制的是,所有的Kye值都必须在 0-n?1之间,且不能有重复值.换言之,他的算法复杂度不由数据的规模 有多 大而决定,而由key值的取值范围而决定. 算导上这一章的讲述方式我非常喜欢,循序渐进,从最基础最简单的一个结构开始,最终