BZOJ 3685 zkw线段树 || 权值线段树
来源:互联网 发布:windows无法访问文件夹 编辑:程序博客网 时间:2024/06/04 18:49
题目链接
思路:
七个操作显然都可以用
前几个操作都很简单,主要复杂于前驱和后继的高效维护。
考虑建立一棵权值线段树,对于值
若
若
分情况讨论即可,对于后继同理。
加上读入挂,8000ms勉强卡过。
而上面3000ms的代码,则使用的是zkw线段树。
因为此题只需要维护前缀和,且自下往上的查找前驱和后继的方式更加快速,并且zkw线段树在内存和编程复杂度上,均比普通的权值线段树简单很多。
代码:
普通权值线段树:
#include<cstdio>using namespace std;#define lson rt<<1#define rson rt<<1|1inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}const int A = 1e6 + 10;class Seg_Tree{public: int l,r,val;}Tree[A<<2];int n,m,op,x;inline void push_up(int rt){Tree[rt].val = Tree[lson].val + Tree[rson].val;}void build(int rt,int l,int r){ Tree[rt].l = l,Tree[rt].r = r;Tree[rt].val = 0; if(l == r) return; int mid = (l+r)>>1; build(lson,l,mid);build(rson,mid+1,r); push_up(rt);}void update(int rt,int v,int c){ int l = Tree[rt].l,r = Tree[rt].r; if(l == r){Tree[rt].val = c;return;} int mid = (l+r)>>1; if(v<=mid) update(lson,v,c); else update(rson,v,c); push_up(rt);}int Mn(int rt){ if(!Tree[rt].val) return -1; int l = Tree[rt].l,r = Tree[rt].r; if(l == r) return l; if(Tree[lson].val) return Mn(lson); else return Mn(rson);}int Mx(int rt){ if(!Tree[rt].val) return -1; int l = Tree[rt].l,r = Tree[rt].r; if(l == r) return l; if(Tree[rson].val) return Mx(rson); else return Mx(lson);}int Find(int rt,int val){ int l = Tree[rt].l,r = Tree[rt].r; if(l == r){ if(Tree[rt].val) return 1; else return -1; } int mid = (l+r)>>1; if(val<=mid) return Find(lson,val); else return Find(rson,val);}int Find_pr(int rt,int val){ if(val<0 || !Tree[rt].val) return -1; int l = Tree[rt].l,r = Tree[rt].r; if(l == r) return l; int mid = (l+r)>>1; if(val <= mid) return Find_pr(lson,val); else{ int tem = Find_pr(rson,val); if(tem == -1) return Mx(lson); return tem; }}int Find_su(int rt,int val){ if(!Tree[rt].val) return -1; int l = Tree[rt].l,r = Tree[rt].r; if(l == r) return l; int mid = (l+r)>>1; if(val>mid) return Find_su(rson,val); else{ int tem = Find_su(lson,val); if(tem == -1) return Mn(rson); return tem; }}int main(){ n = read();m = read(); build(1,0,n); for(int i=1 ;i<=m ;i++){ op = read(); if(op == 1){x=read();update(1,x,1);}else if(op == 2){x=read();update(1,x,0);}else if(op == 3){printf("%d\n",Mn(1));} else if(op == 4){printf("%d\n",Mx(1));} else if(op == 5){x=read();printf("%d\n",Find_pr(1,x-1));}else if(op == 6){x=read();printf("%d\n",Find_su(1,x+1));}else if(op == 7){x=read();printf("%d\n",Find(1,x));} } return 0;}
zkw线段树:
#include<cstdio>using namespace std;#define lson rt<<1#define rson rt<<1|1#define fa rt>>1inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}const int A = 1<<20;int Tree[A<<1|1],M,n,m,op,x;bool vis[A];void update(int rt,int v){for(rt+=M;rt;rt=fa) Tree[rt]+=v;}int Mn(int rt){for(;rt<=M;rt=Tree[lson]?lson:rson);return rt-M-1;}int Mx(int rt){for(;rt<=M;rt=Tree[rson]?rson:lson);return rt-M-1;}int Find_pr(int rt){for(rt+=M ;rt!=1 ;rt=fa){if((rt&1) && Tree[rt^1]) return Mx(rt^1);}return -1;}int Find_su(int rt){for(rt+=M ;rt!=1 ;rt=fa){if(!(rt&1)&& Tree[rt^1]) return Mn(rt^1);}return -1;}int main(){ n = read();m = read(); for(M=1 ;M<=n ;M<<=1); for(int i=1 ;i<=m ;i++){ op = read(); if(op==1){if(!vis[x=read()+1]) vis[x]=1,update(x,1);}else if(op==2){if(vis[x=read()+1]) vis[x]=0,update(x,-1);}else if(op==3){printf("%d\n",Tree[1]?Mn(1):-1);}else if(op==4){printf("%d\n",Tree[1]?Mx(1):-1);}else if(op==5){printf("%d\n",Find_pr(read()+1));}else if(op==6){printf("%d\n",Find_su(read()+1));}else if(op==7){printf("%d\n",vis[read()+1]?1:-1);} } return 0;}
阅读全文
1 0
- BZOJ 3685 zkw线段树 || 权值线段树
- bzoj 3600 zkw线段树+替罪羊树
- BZOJ 3685 普通van Emde Boas树 ZKW线段树
- BZOJ 3685 普通van Emde Boas树 zkw线段树
- BZOJ 3685 普通van Emde Boas树 zkw线段树
- zkw线段树 运用
- 【zkw线段树】ural1855
- ZKW线段树
- POJ3468 ZKW线段树
- ZKW线段树
- zkw线段树 模板
- ZKW线段树
- zkw线段树
- zkw线段树
- zkw线段树分析
- ZKW 线段树
- zkw线段树
- zkw线段树详解
- 关于win10下pip命令出错的解决方法
- 英文学习20170902
- PHP laravel之模型&Eloquent
- C++实现生产者消费者
- 关于微信分享申请应用APPkey时该注意的地方
- BZOJ 3685 zkw线段树 || 权值线段树
- atom编辑器学习笔记
- maven安装eclipse-m2e插件安装
- phaser 背景音乐无限无限循环(7)
- L0和L1:正则化
- Top 8 Diagrams for Understanding Java
- 1019. 数字黑洞 (20) 用时40min【point:排序】
- FM和FFM的区别
- 内存溢出与泄漏