hdu2871 线段树之空间动态存储模拟
来源:互联网 发布:ubuntu 上网命令 编辑:程序博客网 时间:2024/05/17 04:57
昨天晚上分析了一个多小时,晚上敲代码的时候卡住了,后来头脑清醒了才发现自己想复杂了,敲的虽然有点纠结,但整体还是很顺利的,只是又犯了个小错误调了半小时,烦~~~
维护左中右0连续最大值(lc,mc,rc),区间所属模块(block)以及模块左端点数(num).
ACcode:
#include<stdio.h>#include<iostream>using namespace std;const int size=55555;struct Node{ int l,r; int lc,mc,rc; int num,block,lazy; }tre[size<<2];struct Block{ int s,e;}ck[size<<1];int top;int s,e;int Max(int a1,int a2) { return a1>a2?a1:a2; }void clc(int rt){ tre[rt].num=tre[rt].block=0; tre[rt].lc=tre[rt].mc=tre[rt].rc=tre[rt].r-tre[rt].l+1;}void build(int rt,int l,int r){ tre[rt].l=l; tre[rt].r=r; tre[rt].lazy=-1; clc(rt); if (l==r) return ; int m=(l+r)>>1; build(rt<<1,l,m); build(rt<<1|1,m+1,r);}void PushDown(int rt){ if (tre[rt].lazy>=0) { int v=tre[rt].lazy; int r1=rt<<1,r2=r1|1; int k=tre[rt].l+tre[rt].r; int ls=k-(k>>1),rs=k>>1; if (v) { tre[r1].lc=tre[r1].mc=tre[r1].rc=0; tre[r2].lc=tre[r2].mc=tre[r2].rc=0; tre[r1].block=tre[r2].block=tre[rt].block; tre[r1].num=tre[rt].num; tre[r2].num=tre[rt].block=0; } else { clc(r1); clc(r2); } tre[r1].lazy=tre[r2].lazy=tre[rt].lazy; tre[rt].lazy=-1; } }void PushUp(int rt){ int r1=rt<<1,r2=r1|1; tre[rt].num=tre[r1].num+tre[r2].num; tre[rt].lc=tre[r1].lc; if (tre[r1].lc==(tre[r1].r-tre[r1].l+1)) tre[rt].lc+=tre[r2].lc; tre[rt].rc=tre[r2].rc; if (tre[r2].rc==(tre[r2].r-tre[r2].l+1)) tre[rt].rc+=tre[r1].rc; tre[rt].mc=Max(tre[r1].rc+tre[r2].lc,Max(tre[r1].mc,tre[r2].mc));}void update(int rt,int l,int r,int L,int R,int v){ if (L<=l&&r<=R) { if (v) { tre[rt].lc=tre[rt].mc=tre[rt].rc=0; tre[rt].num=(L==l)?1:0; tre[rt].block=v; } else { clc(rt); } tre[rt].lazy=v; return ; } if (l==r) return ; PushDown(rt); int m=(l+r)>>1; if (L<=m) update(rt<<1,l,m,L,R,v); if (R>m) update(rt<<1|1,m+1,r,L,R,v); PushUp(rt);}int querynew(int rt,int l,int r,int v){ if (l==r) return r; PushDown(rt); int m=(l+r)>>1,pos; if (tre[rt<<1].mc>=v) pos=querynew(rt<<1,l,m,v); else if ((tre[rt<<1].rc+tre[rt<<1|1].lc)>=v) pos=m-tre[rt<<1].rc+1; else pos=querynew(rt<<1|1,m+1,r,v); return pos;}int queryfree(int rt,int l,int r,int v){ if (tre[rt].lazy>=0) return tre[rt].lazy; if (l==r) return tre[rt].block; PushDown(rt); int m=(l+r)>>1,tmp; if (v<=m) tmp=queryfree(rt<<1,l,m,v); else tmp=queryfree(rt<<1|1,m+1,r,v); return tmp;}int queryget(int rt,int l,int r,int v){ if (l==r) return tre[rt].block; PushDown(rt); int m=(l+r)>>1,tmp; if (v<=tre[rt<<1].num) tmp=queryget(rt<<1,l,m,v); else tmp=queryget(rt<<1|1,m+1,r,v-tre[rt<<1].num); return tmp;}int main(){ int n,q,x,pos; char op[55]; while (~scanf("%d %d",&n,&q)) { build(1,1,n); top=0; while (q--) { scanf("%s",op); if (op[0]=='N') { scanf("%d",&x); if (tre[1].mc<x) printf("Reject New\n"); else { pos=querynew(1,1,n,x); ck[++top].s=pos; ck[top].e=pos+x-1; printf("New at %d\n",pos); update(1,1,n,pos,pos+x-1,top); } } else if (op[0]=='F') { scanf("%d",&x); pos=queryfree(1,1,n,x); if (!pos) printf("Reject Free\n"); else printf("Free from %d to %d\n",ck[pos].s,ck[pos].e); update(1,1,n,ck[pos].s,ck[pos].e,0); ck[pos].s=ck[pos].e=-1; } else if (op[0]=='G') { scanf("%d",&x); if (tre[1].num<x) printf("Reject Get\n"); else { pos=queryget(1,1,n,x); printf("Get at %d\n",ck[pos].s); } } else { clc(1); tre[1].lazy=0; printf("Reset Now\n"); } } puts(""); } return 0; }
- hdu2871 线段树之空间动态存储模拟
- 线段树 hdu2871 Memory Control
- HDU2871:Memory Control(线段树区间合并)
- hdu2871 Memory Control 线段树,二分
- hdu2871(线段树区间合并+vector+二分)
- 线段树区间维护(各种操作)hdu2871
- hdu2871 Memory Control 线段树区间合并+STL删除插入
- NOIP模拟题 2016.11.9 [动态规划] [数论] [二分答案] [启发式合并] [线段树] [树链剖分]
- NOIP模拟题 2016.11.14 [动态规划] [线段树优化DP] [字符串的复制粘贴DP]
- 线段树为什么要开四倍空间
- 二倍空间的线段树
- NOIP模拟题 [模拟][DP][线段树]
- 动态多分区存储管理模拟系统
- 【模拟+线段树】 hdu4262 Juggler
- 【模拟\线段树\堆】2012
- hdu2795 Billboard 线段树模拟
- hdu 5493线段树+模拟
- python之selenium模拟登录QQ空间
- c++中win32控制台输出宽字符
- android 博客1
- 人,这一辈子
- Android AsyncTask的使用
- 自己动手实现socket的各种超时控制
- hdu2871 线段树之空间动态存储模拟
- CentOS5.8下用“软件包安装工具安装”总是提示:另一个目前运行的程序正在访问软件信息。
- Spring集成Quartz1.8.4版定时任务框架介绍
- Java的位运算符详解实例——与(&)、非(~)、或(|)、异或(^)
- C#中的快捷键,可以更方便的编写代码
- linux内核移植
- springmvc +mybatise 框架的搭建步骤
- libusb 加入到 Android
- svn 常见错误