题目连接: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. 常用python处理try except异常的三种方式

    如果你在写python程序时遇到异常后想进行如下处理的话,一般用try来处理异常,假设有下面的一段程序: try:     语句1     语句2     .     .     语句N except ...

  2. python远程批量执行命令

    #!/usr/bin/env python#-*- coding:utf-8 -*- from multiprocessing import Process,Poolimport time,param ...

  3. python操作----Memcached

    Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度.Memcached ...

  4. span设置宽和高当没有内容的时候也可撑开

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. Qml 定义 constant

    对于程序中一些常量如字符串, 实数等, C++中经常用的方法, 是定义全局常量: 或者把所有意义相近的常量用一个单例类收集起来. QML是类JSON的标识性语言, 使用js 语法去操作对象. 在QML ...

  6. Bullet_Point_Py

    1. if __name__ == "__main__" Term: 模块最高级的代码:模块中没有缩进的代码 Principal 1: 第一次导入模块会执行模块最高级的代码.不管你 ...

  7. shell初学

    超简单的一段shell代码,查看电脑属性,删除无效安装包,查看天气.FYI  #!/bin/bash echo -e '\n' echo "Hello,`whoami`" echo ...

  8. jquery.cookie.js 的配置

    一个轻量级的cookie 插件,可以读取.写入.删除 cookie. jquery.cookie.js 的配置 首先包含jQuery的库文件,在后面包含 jquery.cookie.js 的库文件. ...

  9. top.location != self.location

    top.location != self.location 就是说当前窗体的url和父窗体的 url是不是相同 这个是为了防止别的网站嵌入你的网站的内容(比如用iframe嵌入的你的网站的页面)

  10. Leetcode 136 137 260 SingleNumber I II III

    Leetccode 136 SingleNumber I Given an array of integers, every element appears twice except for one. ...