HDU2871Memory Control(线段树)
来源:互联网 发布:c语言四大圣经先后顺序 编辑:程序博客网 时间:2024/06/07 22:37
题目点这里
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
题目大意:
有n个内存m种操作;
New x :从内存编号1开始分配一个x的空间,如果能则输出这个区间的头地址,如果不能则输出Reject New;
Free x:释放包含x的那个区间,并且输出那个区间的头地址与尾地址,x这个地方不能被释放则输出Reject Free;
Get x:得到第x个区间的头地址,如果这个区间不存在,输出Reject Get;
Reset:释放所有内存清除;
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
思路:
New是找一个x的连续内存那么就用lsum,rsum,sum来维护连续的值;
Free是寻找关于x的最大连续内存的头地址和尾地址,那么就用begin和end表示这个占有内存的段的头和尾;
Reset不再说明;
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
代码:
#include <cstdio>#include <iostream>#include <cstring>using namespace std;struct node{int l,r,ls,rs,s,cover,size,begin,end,lazy;}e[50100*4];//ls,rs,s表示这个区间从最左(右)端开始的最大连续没被占用的内存//size size表示这个区间有几个连续内存 //begin,end表示这个连续内存中的头地址和尾地址 void pushdownsize(int k){ e[k<<1].size = e[k<<1|1].size = 0;e[k<<1].cover = e[k<<1|1].cover = 1; e[k].cover = 0;}void pushupsize(int k){e[k].size = e[k<<1].size + e[k<<1|1].size;}void pushdown(int k){e[k<<1].lazy = e[k<<1|1].lazy = e[k].lazy;e[k<<1].s = e[k<<1].ls = e[k<<1].rs = (e[k<<1].r-e[k<<1].l+1)*e[k<<1].lazy;e[k<<1|1].s = e[k<<1|1].ls = e[k<<1|1].rs = (e[k<<1|1].r - e[k<<1|1].l+1)*e[k<<1|1].lazy;e[k<<1].begin = e[k<<1|1].begin = e[k].begin;e[k<<1|1].end = e[k<<1].end = e[k].end;//一段内存里的所有点的begin和end的是这段内存的头尾地址 e[k].lazy = -1;}void pushup(int k){e[k].ls = e[k<<1].ls;e[k].rs = e[k<<1|1].rs;if(e[k].ls == e[k<<1].r-e[k<<1].l+1)e[k].ls += e[k<<1|1].ls;if(e[k].rs == e[k<<1|1].r-e[k<<1|1].l+1)e[k].rs += e[k<<1].rs;e[k].s = max(max(e[k<<1].s,e[k<<1|1].s),e[k<<1].rs+e[k<<1|1].ls);}void count(int k,int ret,int w){if(e[k].l == e[k].r){e[k].size = w;return;}if(e[k].cover)pushdownsize(k);int mid = (e[k].l + e[k].r)>>1;if(ret > mid)count(k<<1|1,ret,w);if(ret <= mid)count(k<<1,ret,w);pushupsize(k);}void build(int k,int l,int r){e[k].l = l,e[k].r = r,e[k].lazy = -1;e[k].s = e[k].ls = e[k].rs = r-l+1;if(l == r)return;int mid = (l + r)>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);}int find(int k,int ret)//返回长度为ret的空区间的头地址 {if(e[k].l == e[k].r)return e[k].l;if(e[k].lazy != -1)pushdown(k);if(e[k<<1].s >= ret) return find(k<<1,ret); else if(e[k<<1].rs+e[k<<1|1].ls >= ret) return (e[k].l+e[k].r)/2-e[k<<1].rs+1; else if(e[k<<1|1].s >= ret) return find(k<<1|1,ret); pushup(k);}void updata(int k,int l,int r,int flag,int x,int y){if(e[k].l == l && e[k].r == r){e[k].s = e[k].ls = e[k].rs = (e[k].r-e[k].l+1)*flag;e[k].begin = x,e[k].end = y;e[k].lazy = flag;return;}if(e[k].lazy != -1)pushdown(k);int mid = (e[k].l+e[k].r)>>1;if(l > mid)updata(k<<1|1,l,r,flag,x,y);else if(r <= mid)updata(k<<1,l,r,flag,x,y);else{updata(k<<1,l,mid,flag,x,y);updata(k<<1|1,mid+1,r,flag,x,y);}pushup(k);}int search(int k,int ret)//返回关于ret所在的线段树上的代号 {if(e[k].l == e[k].r && e[k].l == ret)return k;if(e[k].lazy != -1)pushdown(k);int mid = (e[k].l+e[k].r)>>1;if(ret > mid)return search(k<<1|1,ret);else if(ret <= mid)return search(k<<1,ret);pushup(k);}int Get(int k,int ret)//找第ret小 {if(e[k].l == e[k].r)return e[k].l;if(e[k].cover)pushdownsize(k);if(e[k<<1].size >= ret)return Get(k<<1,ret);else return Get(k<<1|1,ret-e[k<<1].size);pushupsize(k);}int main(){char s[20];int n,m,ret;while(scanf("%d%d",&n,&m)!=EOF){memset(e,0,sizeof(e));build(1,1,n);for(int i = 1;i <= m;i++){scanf("%s",s); if(!strcmp(s,"Reset")) { puts("Reset Now"); updata(1,1,n,1,0,0); e[1].cover = 1; e[1].size = 0; } if(!strcmp(s,"New")) { scanf("%d",&ret); if(ret > e[1].s)puts("Reject New"); else { int res = find(1,ret); printf("New at %d\n",res); updata(1,res,res+ret-1,0,res,res+ret-1); count(1,res,1); } } if(!strcmp(s,"Free")) { scanf("%d",&ret); int cnt = search(1,ret); if(e[cnt].begin==0)puts("Reject Free"); else { printf("Free from %d to %d\n",e[cnt].begin,e[cnt].end); count(1,e[cnt].begin,0); updata(1,e[cnt].begin,e[cnt].end,1,0,0); } } if(!strcmp(s,"Get")) { scanf("%d",&ret); if(ret > e[1].size)puts("Reject Get"); else printf("Get at %d\n",Get(1,ret)); } } puts("");}return 0;}
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
刷题感悟:
找第K个数在线段树中的操作
关于区间的信息的保存:1.用lsum,rsum,sum来维护连续段;
2.寻找长度并修改,就返回头地址;
3,用begin和end维护头尾地址;
!strcmp(s,""):若s==“ ”返回值为-1;
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
反正啦,这个题是个很经典的裸线段树~~~~~~~~~
- HDU2871Memory Control(线段树)
- HDU 2871 Memory Control(线段树)
- HDU-2871 Memory Control(线段树)
- HDU_2871 Memory Control 线段树
- 线段树 hdu2871 Memory Control
- 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)
- HDU2871:Memory Control(线段树区间合并)
- hdu2871 Memory Control 线段树,二分
- hdu 2871 Memory Control(线段树)
- HDU 2871 Memory Control 线段树
- hdu 2871 Memory Control 线段树
- hdu 2871 Memory Control(线段树)
- hdu 2871 -Memory Control--线段树
- HttpClient + Jsoup 网页数据抓取
- 暴搜 bnu51645 ACM Battle
- 指派问题匈牙利解法以及其优化
- Android学习(41) -- 自定义控件(5)图片轮播(伪循环)
- Adobe Photoshop CS5如何调出标尺和网格
- HDU2871Memory Control(线段树)
- Linux环境下MySQL报Table 'xxx' doesn't exist错误解决方法
- 欢迎使用CSDN-markdown编辑器
- 【图文详解】scrapy安装与真的快速上手——爬取豆瓣9分榜单
- C语言中,为什么字符串可以赋值给字符指针变量
- angular2 will be kiiled by react in the future?
- c单链表基本操作,本人已祥测
- eclipse 配置scala问题-More than one scala library found in the build path
- 第一篇文档,slf4j适配器