bzoj-3685 普通van Emde Boas树 权值线段树+快读!
来源:互联网 发布:株洲中车 知乎 编辑:程序博客网 时间:2024/05/19 02:02
普通van Emde Boas树
题意不再赘述见题面:设计数据结构支持:
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
数据范围和操作数都是1e6级别的,所以普通的set或者treap用起来很方便的是会超时的,所以怎么解决呢?
因为拉的是有关权值线段树的专题,所以很容易想到这个,空间也不会爆,不用离散化,那么每个叶节点代表这个值是否出现过即可,每个节点储存当前区间的最值,只有操作5、6相对比较麻烦,如果前驱的话相当于求[0,x-1]中存在的数的最大值,反之求[x+1,n-1]的最小值,其他的操作比较简单。但写出来竟然TLE了,考虑到数据量比较大。于是加了个快读,8000+ms。荣神将递归改成循环式查找6000+ms,ORZ。
权值线段树+快速读:
const int N=1e6+10;inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}inline int sc(){ char ch=nc(); int sum=0; while(!(ch>='0'&&ch<='9'))ch=nc(); while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc(); return sum;}struct node{ int l,r,num,mi,ma;} a[N<<2];int n,m,c[N];void pushup(int k){ a[k].num=a[k*2].num+a[k*2+1].num; a[k].mi=min((a[k*2].num?a[k*2].mi:INF),(a[k*2+1].num?a[k*2+1].mi:INF)); a[k].ma=max((a[k*2].num?a[k*2].ma:0),(a[k*2+1].num?a[k*2+1].ma:0));}void build(int l,int r ,int k){ a[k].l=l,a[k].r=r,a[k].num=0,a[k].mi=INF,a[k].ma=0; if(l==r) { a[k].ma=a[k].mi=l; c[l]=0; return ; } int mid=(l+r)/2; build(l,mid,2*k); build(mid+1,r,2*k+1);}void update(int id,int f,int k)//支持插入或删除{ if(a[k].l==id&&a[k].r==id) { if(f==1&&!a[k].num) { a[k].num^=1; c[id]=1; } else if(f==2&&a[k].num) { a[k].num^=1; c[id]=0; } return ; } int mid=(a[k].l+a[k].r)/2; if(id<=mid) update(id,f,k*2); else update(id,f,k*2+1); pushup(k);}int query(int l,int r,int f,int k)//求前驱或后继{ if(r<l) return INF; if(a[k].l==l&&a[k].r==r) { if(!a[k].num) return INF; return f==1?a[k].ma:a[k].mi; } int mid=(a[k].l+a[k].r)/2; if(r<=mid) return query(l,r,f,2*k); if(l>mid) return query(l,r,f,2*k+1); else { int tmp1=query(l,mid,f,2*k); int tmp2=query(mid+1,r,f,2*k+1); if(tmp1==INF&&tmp2!=INF) return tmp2; else if(tmp1!=INF&&tmp2==INF) return tmp1; return (f==1)?max(tmp1,tmp2):min(tmp1,tmp2); }}int main(){ while(~scanf("%d%d",&n,&m)) { build(0,n,1); while(m--) { int x,y; x=sc(); if(x==3||x==4) { if(!a[1].num) puts("-1"); else printf("%d\n",x==3?a[1].mi:a[1].ma); continue; } y=sc(); if(x==1||x==2) update(y,x,1); else if(x==7) { if(c[y]) puts("1"); else puts("-1"); } else { int tmp=INF; if(x==5) tmp=query(0,y-1,1,1); else tmp=query(y+1,n-1,2,1); if(tmp==INF) puts("-1"); else printf("%d\n",tmp); } } } return 0;}
荣神大佬:
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define MAX 1000010#define LEFT (pos << 1)#define RIGHT (pos << 1 | 1)using namespace std; int range, asks, M;int tree[MAX << 2]; inline void Modify(int pos, int c){ tree[pos] += c; for (; pos; pos >>= 1) tree[pos] += c;} inline int GetMin(int pos){ if (!tree[pos]) return 0; while (pos <= M) { if (tree[LEFT]) pos = LEFT; else pos = RIGHT; } return pos - M;} inline int GetMax(int pos){ if (!tree[pos]) return 0; while (pos <= M) { if (tree[RIGHT]) pos = RIGHT; else pos = LEFT; } return pos - M;} inline int GetPred(int x){ int pos = x + M; while (1) { if (pos == 1) return 0; if (pos & 1 && tree[pos ^ 1]) return GetMax(pos ^ 1); pos >>= 1; } return 0;} inline int GetSucc(int x){ int pos = x + M; while (1) { if (pos == 1) return 0; if (!(pos & 1) && tree[pos ^ 1]) return GetMin(pos ^ 1); pos >>= 1; } return 0;} int main(){ cin >> range >> asks; for (M = 1; M <= range; M <<= 1) ; for (int x, flag, i = 1; i <= asks; ++i) { scanf("%d", &flag); if (flag == 1) { scanf("%d", &x); ++x; if (!tree[M + x]) Modify(M + x, 1); } else if (flag == 2) { scanf("%d", &x); ++x; if (tree[M + x]) Modify(M + x, -1); } else if (flag == 3) printf("%d\n", GetMin(1) - 1); else if (flag == 4) printf("%d\n", GetMax(1) - 1); else if (flag == 5) { scanf("%d", &x); ++x; printf("%d\n", GetPred(x) - 1); } else if (flag == 6) { scanf("%d", &x); ++x; printf("%d\n", GetSucc(x) - 1); } else { scanf("%d", &x); ++x; printf("%d\n", tree[x + M] ? 1 : -1); } } return 0;}
阅读全文
0 0
- bzoj-3685 普通van Emde Boas树 权值线段树+快读!
- BZOJ 3685 普通van Emde Boas树 ZKW线段树
- BZOJ 3685 普通van Emde Boas树 zkw线段树
- BZOJ 3685 普通van Emde Boas树 zkw线段树
- BZOJ 3685 普通van Emde Boas树
- BZOJ 3685 普通van Emde Boas树
- 【BZOJ 3685】普通van Emde Boas树【treap】
- bzoj 3685 普通van Emde Boas树(坑)
- 【BZOJ】【P3685】【普通van Emde Boas树】【题解】【vEB树】
- 【bzoj3685】【普通van Emde Boas树】【线段树】
- BZOJ3685 普通van Emde Boas树
- [BZOJ3685]普通van Emde Boas树
- BZOJ3685: 普通van Emde Boas树
- BZOJ3685普通van Emde Boas树
- BZOJ3685 普通van Emde Boas树
- bzoj3685: 普通van Emde Boas树
- van Emde Boas树
- 3685: 普通van Emde Boas树——set
- 数据结构与算法 第一课
- Zookeeper与Paxos
- Mybatis实现原理/工作流程
- 简单实现日期计算器的基本功能
- 基于springboot ThreadPoolTaskScheduler类实现定时任务动态添加修改
- bzoj-3685 普通van Emde Boas树 权值线段树+快读!
- [leetcode] 第三周作业
- 纯css,div隐藏滚动条,保留鼠标滚动效果。
- 一秒搞定合并单元格编号
- XML中必须进行转义的字符
- LSTM学习笔记
- DB2函数
- DB2 -803等错误码对照
- @DeclareParents为某个类及其所有子类动态代理新增实现接口