hdu_2871_Memory Control(巨恶心线段树)
题目连接: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(巨恶心线段树)的更多相关文章
- 洛谷P4243/bzoj1558 [JSOI2009]等差数列(线段树维护差分+爆炸恶心的合并)
题面 首先感谢这篇题解,是思路来源 看到等差数列,就会想到差分,又有区间加,很容易想到线段树维护差分.再注意点细节,\(A\)操作完美解决 然后就是爆炸恶心的\(B\)操作,之前看一堆题解的解释都不怎 ...
- hdu 2871 Memory Control(线段树)
题目链接:hdu 2871 Memory Control 题目大意:模拟一个内存分配机制. Reset:重置,释放全部空间 New x:申请内存为x的空间,输出左地址 Free x:释放地址x所在的内 ...
- BZOJ 4373 算术天才⑨与等差数列 线段树+set(恶心死我了)
mdzz,这道题重构了4遍,花了一个晚上... 满足等差数列的条件: 1. 假设min是区间最小值,max是区间最大值,那么 max-min+k(r−l) 2. 区间相邻两个数之差的绝对值的gcd=k ...
- 【BZOJ-1858】序列操作 线段树
1858: [Scoi2010]序列操作 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1961 Solved: 991[Submit][Status ...
- BZOJ 4942 NOI2017 整数 (压位+线段树)
题目大意:让你维护一个数x(x位数<=3*1e7),要支持加/减a*2^b,以及查询x的第i位在二进制下是0还是1 作为一道noi的题,非常考验写代码综合能力,敲+调+借鉴神犇的代码 3个多小时 ...
- BZOJ-3228 棋盘控制 线段树+扫描线+鬼畜毒瘤
3228: [Sdoi2008]棋盘控制 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 23 Solved: 9 [Submit][Status][D ...
- POJ-2299 Ultra_QuickSort 线段树+逆序对数
Ultra-QuickSort Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 50737 Accepted: 18595 Des ...
- A线段树
线段树专题 顾琪坤 1.简介: 打acm的时候,经常会碰到一类问题,比方给你n个数的序列,然后动态的更改某些数的值,然后又动态地询问某个区间的值的和或者其它乱七八糟的东西,对于单个更改或者询问,也许很 ...
- Stars(树状数组或线段树)
Stars Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 37323 Accepted: 16278 Description A ...
随机推荐
- NSLineBreakMode
typedef enum { UILineBreakModeWordWrap = 0, UILineBreakModeCharacterWrap, UILineBreakModeCl ...
- 初识Spark(Spark系列)
1.Spark Spark是继Hadoop之后,另外一种开源的高效大数据处理引擎,目前已提交为apach顶级项目. 效率: 据官方网站介绍,Spark是Hadoop运行效率的10-100倍(随内存计算 ...
- mysql for windows zip版安装
1.将mysql_5.6.24_winx64.zip 解压到文件夹 2.增加环境变量 3.修改mysql配置文件 将mysql根目录下的my-default.ini 复制一份更名为 my.ini.修改 ...
- C/C++中整数与浮点数在内存中的表示方式
在C/C++中数字类型主要有整数与浮点数两种类型,在32位机器中整型占4字节,浮点数分为float,double两种类型,其中float占4字节,而double占8字节.下面来说明它们在内存中的具体表 ...
- @@identity的用法
问题描述:两张表,比如说A表和B表.A表中的id为自增的,B表中的id为外键,插入时不能为空. 解决办法: 用select @@identity得到上一次插入记录时自动产生的ID,将@@identit ...
- Glide加载圆形图片
方案1:经过验证,可以完美实现 Glide.with(context).load(url).asBitmap().centerCrop().into(new BitmapImageViewTarge ...
- 纯 CSS 实现三角形尖角箭头的实例
上次无意中发现了个使用纯 CSS 实现三角形尖角箭头的方法 http://blog.csdn.net/zhouzme/article/details/18901943 ,但没有怎么用上,也没有详细完整 ...
- lt>&eq
lt:less than,小于 gt:greater than,大于 eq:equal,等于 le:less equal,小于等于 ge:greater than,大于等于
- 阻塞与非阻塞、同步与异步 I/O模型
I/O模型 Linux 下的五种I/O模型 阻塞I/O(blocking I/O) 非阻塞I/O (nonblocking I/O) I/O复用(select 和poll) (I/O multiple ...
- Android的JunitTest
1.在manifest的配置:首先,manifest的下层级中配置: <instrumentation android:name="android.test.Instrumentati ...