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 ...
随机推荐
- 常用到的简单命令 Sublime Git NPM WindowsCMD MacTerminal(Unix命令)
sublime 选择标签及其内容 ctrl+shift+a连续按两次 Git 撤销 add 重置暂存区的指定文件,与上一次commit保持一致,但工作区不变 git reset [file] 撤销 c ...
- 解决ubuntu 里面vi的时候上下左右是ABCD删除也不起作用
解决ubuntu 里面vi的时候上下左右是ABCD,backspace也不起作用 cp /etc/vim/vimrc ~/.vimrc 用remove vim-common然后再install v ...
- Web多客户端单点登录
一 数据库 除了用户表之外,新建一个外联表<用户票据表> fdUsTiUserID,fdUsTiType,fdUsTiTicket 分别对应用户ID,客户端类型(PC,mobile) 票 ...
- java 中文乱码
1.URL编码 String str = URLEncoder.encode("中文乱码","UTF-8");//编码 String newStr = URLD ...
- Generating Faces with Deconvolution Networks
用深度学习做人脸合成,website:https://zo7.github.io/blog/2016/09/25/generating-faces.html 受启发于 Learning to Gene ...
- Chapter 2 Open Book——30
I looked down. His hands were clenched into hard fists again. 我向下看,他的双手又一次收紧握成拳头. Mr. Banner came to ...
- 第三节,入门知识和windows系统安装python环境
1.使用Linux的好处(稳定)不容易死机,可以长达几年不间断运行(安全)相对windows系统更安全,相对更不容受到各种攻击(开源)免费使用2.安装好虚拟机VMware软件,和Linux系统,以及X ...
- Java Object 对象创建的方式 [ 转载 ]
Java Object 对象创建的方式 [ 转载 ] @author http://blog.csdn.net/mhmyqn/article/details/7943411 显式创建 有4种显式地创建 ...
- webapi中使用Route标签
Prior to Web API 2, the Web API project templates generated code like this: protected void Applicati ...
- BestCoder Round #85 A B C
本来没有写博客的打算,可是看完了题解感觉这三道题这么水,我却只做出来一道,实在不应该,还是写点东西吧…… A.sum 问题描述 给定一个数列,求是否存在连续子列和为m的倍数,存在输出YES,否则输出N ...