HDU 2871 Memory Control (线段树神题)
来源:互联网 发布:linux下路由跟踪命令 编辑:程序博客网 时间:2024/06/05 18:09
神题。。综合了线段树的所有操作,很锻炼代码能力。
初状态全为0
ls,ms,rs记录区间连续的0,lv,rv记录其所属block的左右端点,c为其懒标记,
cnt记录区间的block数,clr记录是否重置。
代码:
#include<iostream>#include<cstdio>#include<algorithm>#define lson l , m , rt<<1#define rson m+1,r , rt<<1|1using namespace std;typedef long long LL;const int maxn = 80005;struct SegTree{ int ls[maxn<<2],ms[maxn<<2],rs[maxn<<2],c[maxn<<2]; int cnt[maxn<<2],clr[maxn<<2]; int lv[maxn<<2],rv[maxn<<2]; void push_up(int l,int r,int rt){ int m = (l + r) >> 1; ms[rt] = max(max(ms[rt<<1],ms[rt<<1|1]),rs[rt<<1]+ls[rt<<1|1]); ls[rt] = ls[rt<<1] == m-l+1 ? ls[rt<<1]+ls[rt<<1|1] : ls[rt<<1]; rs[rt] = rs[rt<<1|1] == r-m ? rs[rt<<1|1]+rs[rt<<1] : rs[rt<<1|1]; } void push_down(int l,int r,int rt){ if(c[rt] == -1) return; int m = (l + r) >> 1; c[rt<<1] = c[rt<<1|1] = c[rt]; if(c[rt]) ms[rt<<1] = ls[rt<<1] = rs[rt<<1] = ms[rt<<1|1] = ls[rt<<1|1] = rs[rt<<1|1] = 0; else{ ms[rt<<1] = ls[rt<<1] = rs[rt<<1] = m-l+1; ms[rt<<1|1] = ls[rt<<1|1] = rs[rt<<1|1] = r-m; } lv[rt<<1] = lv[rt<<1|1] = lv[rt]; rv[rt<<1] = rv[rt<<1|1] = rv[rt]; c[rt] = -1; } void cnt_up(int rt){ cnt[rt] = cnt[rt<<1] + cnt[rt<<1|1]; } void clear(int l,int r,int rt){ if(clr[rt] == 0) return; clr[rt<<1] = clr[rt<<1|1] = clr[rt]; cnt[rt<<1] = cnt[rt<<1|1] = clr[rt] = 0; } void build(int l,int r,int rt){ c[rt] = lv[rt] = rv[rt] = -1;clr[rt] = cnt[rt] = 0; if(l == r){ ls[rt] = ms[rt] = rs[rt] = 1; return; } int m = (l + r) >> 1; build(lson);build(rson); push_up(l,r,rt); } int New(int x,int l,int r,int rt){ if(ms[rt] < x) return -1; if(l == r) return l; push_down(l,r,rt); int m = (l + r) >> 1; if(ms[rt<<1] >= x) return New(x,lson); else if(rs[rt<<1]+ls[rt<<1|1] >= x) return m-rs[rt<<1]+1; else return New(x,rson); } int Free(int x,int l,int r,int rt){ if(l == r) return rt; push_down(l,r,rt); int m = (l + r) >> 1; if(m >= x) return Free(x,lson); else return Free(x,rson); } int Get(int x,int l,int r,int rt){ if(cnt[rt] < x) return -1; if(l == r) return l; clear(l,r,rt); int m = (l + r) >> 1; if(cnt[rt<<1] >= x) return Get(x,lson); else return Get(x-cnt[rt<<1],rson); } void MemFill(int a,int b,int x,int l,int r,int rt){ if(l > b || r < a) return; if(a <= l && r <= b){ ms[rt] = ls[rt] = rs[rt] = x ? 0 : r-l+1; lv[rt] = x ? a : -1; rv[rt] = x ? b : -1; c[rt] = x; return; } push_down(l,r,rt); int m = (l + r) >> 1; MemFill(a,b,x,lson);MemFill(a,b,x,rson); push_up(l,r,rt); } void update(int k,int x,int l,int r,int rt){ if(l == r){ cnt[rt] = x; return; } clear(l,r,rt); int m = (l + r) >> 1; if(m >= k) update(k,x,lson); else update(k,x,rson); cnt_up(rt); }}sol;int main(){ int n,q,x;char ch[10]; while(~scanf("%d%d",&n,&q)){ sol.build(1,n,1); while(q--){ scanf("%s",ch); if(ch[0] == 'R'){ sol.cnt[1] = 0; sol.clr[1] = 1; sol.MemFill(1,n,0,1,n,1); printf("Reset Now\n"); }else{ scanf("%d",&x); if(ch[0] == 'N'){ int pos = sol.New(x,1,n,1); if(pos == -1) printf("Reject New\n"); else{ sol.MemFill(pos,pos+x-1,1,1,n,1); sol.update(pos,1,1,n,1); printf("New at %d\n",pos); } }else if(ch[0] == 'F'){ int pos = sol.Free(x,1,n,1); if(sol.lv[pos] < 0) printf("Reject Free\n"); else{ printf("Free from %d to %d\n",sol.lv[pos],sol.rv[pos]); sol.update(sol.lv[pos],0,1,n,1); sol.MemFill(sol.lv[pos],sol.rv[pos],0,1,n,1); } }else{ int pos = sol.Get(x,1,n,1); if(pos == -1) printf("Reject Get\n"); else printf("Get at %d\n",pos); } } } putchar('\n'); } return 0;}
0 0
- HDU 2871 Memory Control (线段树神题)
- hdu 2871 Memory Control 线段树
- 线段树 HDU 2871 memory control
- hdu 2871 vector + 线段树 Memory Control
- 线段树 hdu 2871 memory control
- hdu 2871 Memory Control (线段树&vector)
- hdu 2871 Memory Control(线段树)
- HDU 2871 Memory Control 线段树
- hdu 2871 Memory Control 线段树
- hdu 2871 Memory Control(线段树)
- HDU 2871 Memory Control(线段树)
- HDU-2871 Memory Control(线段树)
- hdu 2871 -Memory Control--线段树
- HDU 2871 Memory Control(线段树:区间合并)
- HDU 2871 Memory Control (线段树,区间合并)
- HDU 2871 Memory Control(线段树区间合并+二分)
- HDU 2871 Memory Control(线段树+区间合并+vector)
- hdu 2871 Memory Control
- 目录下有个.h.gch文件,是什么?
- 记录android5.0更新踩过的坑
- 手动编译安装LAMP架构,并且实现nagios图形化监控(十二)
- “激进”与“保守”“左派”与“右派”
- python 协程示例
- HDU 2871 Memory Control (线段树神题)
- c_c++刁钻问题各个击破之位运算及其实例(2)
- poj1306+double就够了不过以后double用%lf
- Mybatis学习笔记-一级缓存
- Android在ListView中嵌套一个GridView时只显示一行的原因及解决方法
- hdu 1540/POJ 2892 Tunnel Warfare 【线段树区间合并】
- uva10820(欧拉函数)
- Hibernate单向关联N-N
- 【DP】poj1692