题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2871

题意:给你一段内存,让你操作1:Reset:重置所有内存 2:New x:申请一块X大小的内存,返回内存最左边的开头,3:free x:释放包含x单元的内存块 4:Get x:取第X块的内存首地址

题解:这题我写了一晚上,很恶心,显然用线段树维护,不过用一个Vector 来应对 free和get操作比较方便,线段树就只需要维护内存的连续长度和最大长度就行了,

ll[rt]为该区段从左边开始的连续内存长度,rr[rt]为该区间从右边开始的连续内存长度,mlen[rt]为该区间最大的连续内存长度,只有这样维护才能在线段树中任意操作区间

 #include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
#define F(i,a,b) for(int i=a;i<=b;i++)
#define root 1,n,1
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define Max(a,b) ((a)>(b)?(a):(b)) struct edge{
int l,r;
bool operator<(const edge &b)const{return l<b.l;}
}s,e,tp;
const int maxn=;
int n,m,num,ll[maxn<<],rr[maxn<<],lazy[maxn<<],mlen[maxn<<];
vector<edge>Q; inline void pup(int l,int r,int rt){
int m=(l+r)>>;
mlen[rt]=Max(mlen[rt<<],mlen[rt<<|]);
mlen[rt]=Max(mlen[rt],rr[rt<<]+ll[rt<<|]);
ll[rt]=ll[rt<<]+(ll[rt<<]==m-l+?ll[rt<<|]:);
rr[rt]=rr[rt<<|]+(rr[rt<<|]==r-m?rr[rt<<]:);
} inline void pdown(int l,int r,int rt){
if(lazy[rt]!=-){
lazy[rt<<]=lazy[rt<<|]=lazy[rt];
int m=(l+r)>>;
mlen[rt<<]=ll[rt<<]=rr[rt<<]=(lazy[rt]==?m-l+:);
mlen[rt<<|]=rr[rt<<|]=ll[rt<<|]=(lazy[rt]==?r-m:);
lazy[rt]=-;
}
} int New(int l,int r,int rt,int num){
if(l==r)return l;
int m=(l+r)>>;
pdown(l,r,rt);
if(mlen[rt<<]>=num)return New(ls,num);
else if(rr[rt<<]+ll[rt<<|]>=num)return m-rr[rt<<]+;
else return New(rs,num);
} void covr(int op,int L,int R,int l,int r,int rt){//op为0是释放内存,1为占用
if(L<=l&&r<=R){
lazy[rt]=op,ll[rt]=rr[rt]=mlen[rt]=(op==?r-l+:);
return;
}
pdown(l,r,rt);
int m=(l+r)>>;
if(L<=m)covr(op,L,R,ls);
if(R>m)covr(op,L,R,rs);
pup(l,r,rt);
} void reset(){Q.clear(),Q.push_back(s),Q.push_back(e);covr(,,n,root);} void insert(edge xx){
int now=upper_bound(Q.begin(),Q.end(),xx)-Q.begin();
Q.insert(Q.begin()+now,xx);
} int main(){
char op[];s.l=,s.r=,e.l=,e.r=;
while(~scanf("%d%d",&n,&m)){
reset();
while(m--){
scanf("%s",op);
if(op[]!='R')scanf("%d",&num);
if(op[]=='N')if(mlen[]<num)puts("Reject New");
else{int x=New(root,num);printf("New at %d\n",x),tp.l=x,tp.r=x+num-,covr(,tp.l,tp.r,root),insert(tp);}
else if(op[]=='F'){
tp.l=num,tp.r=num;
int now=upper_bound(Q.begin(),Q.end(),tp)-Q.begin()-;
if(Q[now].l<=num&&Q[now].r>=num)
covr(,Q[now].l,Q[now].r,root),printf("Free from %d to %d\n",Q[now].l,Q[now].r),Q.erase(Q.begin()+now);
else puts("Reject Free");
}else if(op[]=='G'){
if(num>Q.size()-)puts("Reject Get");
else printf("Get at %d\n",Q[num].l);
}else reset(),puts("Reset Now");
}
puts("");
}
return ;
}

hdu_2871_Memory Control(巨恶心线段树)的更多相关文章

  1. 洛谷P4243/bzoj1558 [JSOI2009]等差数列(线段树维护差分+爆炸恶心的合并)

    题面 首先感谢这篇题解,是思路来源 看到等差数列,就会想到差分,又有区间加,很容易想到线段树维护差分.再注意点细节,\(A\)操作完美解决 然后就是爆炸恶心的\(B\)操作,之前看一堆题解的解释都不怎 ...

  2. hdu 2871 Memory Control(线段树)

    题目链接:hdu 2871 Memory Control 题目大意:模拟一个内存分配机制. Reset:重置,释放全部空间 New x:申请内存为x的空间,输出左地址 Free x:释放地址x所在的内 ...

  3. BZOJ 4373 算术天才⑨与等差数列 线段树+set(恶心死我了)

    mdzz,这道题重构了4遍,花了一个晚上... 满足等差数列的条件: 1. 假设min是区间最小值,max是区间最大值,那么 max-min+k(r−l) 2. 区间相邻两个数之差的绝对值的gcd=k ...

  4. 【BZOJ-1858】序列操作 线段树

    1858: [Scoi2010]序列操作 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1961  Solved: 991[Submit][Status ...

  5. BZOJ 4942 NOI2017 整数 (压位+线段树)

    题目大意:让你维护一个数x(x位数<=3*1e7),要支持加/减a*2^b,以及查询x的第i位在二进制下是0还是1 作为一道noi的题,非常考验写代码综合能力,敲+调+借鉴神犇的代码 3个多小时 ...

  6. BZOJ-3228 棋盘控制 线段树+扫描线+鬼畜毒瘤

    3228: [Sdoi2008]棋盘控制 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 23 Solved: 9 [Submit][Status][D ...

  7. POJ-2299 Ultra_QuickSort 线段树+逆序对数

    Ultra-QuickSort Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 50737 Accepted: 18595 Des ...

  8. A线段树

    线段树专题 顾琪坤 1.简介: 打acm的时候,经常会碰到一类问题,比方给你n个数的序列,然后动态的更改某些数的值,然后又动态地询问某个区间的值的和或者其它乱七八糟的东西,对于单个更改或者询问,也许很 ...

  9. Stars(树状数组或线段树)

    Stars Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 37323 Accepted: 16278 Description A ...

随机推荐

  1. Spring MVC(二)

    spring mvc工作流 1A)客户端发出http请求,只要请求形式符合web.xml 文件中配置的*.action的话,就由DispatcherServlet 来处理. 1B)Dispatcher ...

  2. win10系统 L2TP连接尝试失败:ERROR因为安全层在初始化与远程计算机的协商时遇到了一个处理错误

    1 确保IPsec Policy Agent服务已启动 2 确保路由和远程访问(Routing and Remote Access)和远程访问连接管理器服务(Remote Access Connect ...

  3. mysql innodb存储引擎和myisam引擎

    InnoDb存储引擎面向在线事务处理,其特点是行锁设计.支持外键.并支持Oricle似得非锁定读(所谓非锁定读是如果数据库实例读取的行正在进行更新或删除操作当前读取不会等待当前锁的释放而是读取当前行的 ...

  4. The most orzed and orzing man

    The most orzed and orzing man 题目链接:http://acm.xidian.edu.cn/problem.php?id=1184 Sprague-Grundy定理:htt ...

  5. js--闭包的理解

    从技术上来讲,在JS中,每个function都是闭包,因为它总是能访问在它外部定义的数据. 当该内部函数在外部函数外被调用,就生成了闭包. 函数内部可以直接读取全局变量. 闭包就是能够读取其他函数内部 ...

  6. iOS开发Embedded dylibs/frameworks are only supported on iOS 8.0 and later for architecture armv7的解决方法

    全局搜索IPHONEOS_DEPLOYMENT_TARGE改为更小的版本

  7. JavaScript的计时器对象

    1.JavaScript计时器,我们可以在设定的时间间隔之后来执行代码,而不是在函数被调用后立即执行. 计时器类型:    1)一次性计时器:仅在指定的延迟时间之后触发一次.    2)间隔性触发计时 ...

  8. offsetWidth,offsetHeight到底该如何理解?

    1.对象的可见宽度(对象指body.div等) 2.offsetWidth可以返回div的宽 3.offsetWidth=width+padding+border(不包括margin外边距) 4.返回 ...

  9. nginx在linux下的目录结构

    配置文件目录 putty 下  whereis nginx /etc/nginx

  10. 3种日志类型,微信付款反馈-->写入txt日志

    --> 接收  $GLOBALS["HTTP_RAW_POST_DATA"] ---->xml 反系列化$qr = XML_unserialize( $rowpost ...