链接:http://acm.hdu.edu.cn/showproblem.php?pid=2871

题意:

四种操作:

1.Reset  清空所有内存
2.New x  分配一个大小为x的内存块返回,返回能分配的最小的起始点

3.Free x  释放当前点所在的内存块,并输出左右端点

4.Get x  返回第x个内存块的起始点

讨论每个操作的写法:

第一个操作,把线段树初始化就好了

第二个操作,区间合并的基础操作,

第三个操作:多维护两个数组:st,ed代表当前点所属内存块的左右区间

第四个操作:再开棵树,存每个内存块的起始点,每个起始点下标+1,然后直接找第k大就好了。注意每次2,3,操作内存块发生变化时记得更新这个树上的信息。

题面说了每组数据中间要有空行,不然会PE.

实现代码:

#include<bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mid int m = (l + r) >> 1
#define ls rt<<1
#define rs rt<<1|1
const int M = 1e5 + ;
int lsum[M<<],rsum[M<<],sum[M<<],lazy[M<<],st[M<<],ed[M<<];
int cnt[M<<],cov[M<<],n;
void pushup(int l,int r,int rt){
mid;
lsum[rt] = lsum[ls]; rsum[rt] = rsum[rs];
sum[rt] = max(sum[ls],sum[rs]);
if(lsum[rt] == m-l+) lsum[rt] += lsum[rs];
if(rsum[rt] == r-m) rsum[rt] += rsum[ls];
sum[rt] = max(rsum[ls]+lsum[rs],sum[rt]);
} void pushdown(int l,int r,int rt){
if(lazy[rt]!=-){
mid;
lazy[ls] = lazy[rs] = lazy[rt];
sum[ls] = lsum[ls] = rsum[ls] = (m-l+)*lazy[rt];
sum[rs] = lsum[rs] = rsum[rs] = (r-m)*lazy[rt];
st[ls] = st[rs] = st[rt];
ed[ls] = ed[rs] = ed[rt];
lazy[rt] = -;
}
} void update(int L,int R,int c,int l,int r,int rt){
if(L <= l&&R >= r){
lazy[rt] = c;
lsum[rt] = rsum[rt] = sum[rt] = (r-l+)*c;
if(c) st[rt] = ed[rt] = -;
else{
st[rt] = L; ed[rt] = R;
}
return ;
}
pushdown(l,r,rt);
mid;
if(L <= m) update(L,R,c,lson);
if(R > m) update(L,R,c,rson);
pushup(l,r,rt);
} void rebuild(){
update(,n,,,n,);
//cout<<sum[1]<<endl;
cnt[] = ;
cov[] = ;
} int New(int p,int l,int r,int rt){ //返回空位的左边界
if(l == r) return l;
mid;
pushdown(l,r,rt);
if(sum[ls] >= p) return New(p,lson);
else if(rsum[ls]+lsum[rs]>=p) return m-rsum[ls]+;
else return New(p,rson);
} int Free(int p,int l,int r,int rt){
if(l == r) return rt;
mid;
pushdown(l,r,rt);
if(p <= m) return Free(p,lson);
else return Free(p,rson);
} void up(int rt){
cnt[rt] = cnt[ls] + cnt[rs];
} void down(int rt){
if(cov[rt]){
cnt[ls] = cnt[rs] = ;
cov[ls] = cov[rs] = ;
cov[rt] = ;
}
} int get(int p,int l,int r,int rt){
if(l == r) return l;
mid;
down(rt);
if(cnt[ls] >= p) return get(p,lson);
else return get(p-cnt[ls],rson);
} void change(int p,int c,int l,int r,int rt){
if(l == r){
cnt[rt] = c;
return;
}
down(rt);
mid;
if(p <= m) change(p,c,lson);
else change(p,c,rson);
up(rt);
} int main()
{
int q,k,x;
while(scanf("%d%d",&n,&q)!=EOF){
rebuild();
while(q--){
char op[];
scanf("%s",op);
if(op[] == 'N'){
scanf("%d",&x);
//cout<<sum[1]<<" "<<x<<endl;
if(sum[] < x) printf("Reject New\n");
else{
int k = New(x,,n,);
printf("New at %d\n",k);
change(k,,,n,);
update(k,k+x-,,,n,);
}
}
else if(op[]=='F'){
scanf("%d",&x);
int k = Free(x,,n,);
if(st[k] < ) printf("Reject Free\n");
else{
printf("Free from %d to %d\n",st[k],ed[k]);
change(st[k],,,n,);
update(st[k],ed[k],,,n,);
}
}
else if(op[] == 'R'){
rebuild();
printf("Reset Now\n");
}
else{
scanf("%d",&x);
if(x > cnt[])
printf("Reject Get\n");
else
printf("Get at %d\n",get(x,,n,));
}
}
printf("\n");
}
return ;
}

hdu 2871 Memory Control (区间合并 连续段的起始位置 点所属段的左右端点)的更多相关文章

  1. hdu 2871 Memory Control(伸展树splay tree)

    hdu 2871 Memory Control 题意:就是对一个区间的四种操作,NEW x,占据最左边的连续的x个单元,Free x 把x单元所占的连续区间清空 , Get x 把第x次占据的区间输出 ...

  2. hdu 2871 Memory Control(线段树)

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

  3. HDU 2871 Memory Control

    一共4种操作 其中用线段树 区间合并,来维护连续空的长度,和找出那个位置.其他用vector维护即可 #include<cstring> #include<cstdio> #i ...

  4. ●HDU 2871 Memory Control(Splay)

    ●赘述题目 四种操作: ○Reset:将整个内存序列清空. ○New a:在尽量靠左的位置新建一个长度为a的内存块,并输出改内存块起始位置.(各个内存块即使相邻也不会合并..) ○Free a:将a点 ...

  5. HDU 2871"Memory Control"(线段树区间和并+set.lower_bound)

    传送门 •题意 有 n 个内存单元(编号从1开始): 给出 4 种操作: (1)Reset :表示把所有的内存清空,然后输出 "Reset Now". (2)New x :表示申请 ...

  6. HDU 3911 线段树区间合并、异或取反操作

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...

  7. HDU 4553 约会安排 (区间合并)【线段树】

    <题目链接> 寒假来了,又到了小明和女神们约会的季节.  小明虽为屌丝级码农,但非常活跃,女神们常常在小明网上的大段发言后热情回复“呵呵”,所以,小明的最爱就是和女神们约会.与此同时,也有 ...

  8. hdu 3308(线段树区间合并)

    LCIS Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  9. HDU 3308 LCIS (经典区间合并)【线段树】

    <题目链接> 题目大意: 给你一段序列,对其进行两种操作,一是修改某个序号的点的值:二是查询某个区间的LCIS(最长上升子序列). 解题分析: 线段树区间合并的典型例题,用求某个区间的LC ...

随机推荐

  1. Chrome浏览器设置自动启用Flash插件

    Chrome浏览器设置自动启用Flash插件   1.打开Chrome浏览器,输入chrome://flags/#run-all-flash-in-allow-mode,打开,找到Enable Eph ...

  2. (WA)BZOJ 4821: [Sdoi2017]相关分析

    二次联通门 : BZOJ 4821: [Sdoi2017]相关分析 2017.8.23 Updata 妈妈!!这道题卡我!!!就是不然我过!!!!! #include <cstdio> # ...

  3. php win/linux/mac 安装redis扩展或者扩展报错 zend_smart_str.h file not found

    1 windows 安装reids 扩展 根据phpinfo 查看php信息.在pecl.php.net 下载对应的redis扩展版本,放如扩展目录,在php.ini 配置扩展信息,重启服务 2 li ...

  4. CodeForces - 999C Alphabetic Removals

    C - Alphabetic Removals ≤k≤n≤4⋅105) - the length of the string and the number of letters Polycarp wi ...

  5. element-ui下拉按钮的用法

    <el-dropdown class="avatar-container" trigger="click"> <div class=" ...

  6. MySQL数据分析-(9)库操作补充:用户管理和权限管理

    大家好,我是jacky,很高兴继续跟大家学习MySQL数据分析实战,本节课的主题是用户管理和权限管理: 在分享之前,jacky在不厌其烦的强调一下:学习任何一门学科和技能,最重要的是捋清逻辑,我们要知 ...

  7. 爬虫之解析库BeautifulSoup

    介绍 Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据.官方解释如下: Beautiful Soup提供一些简单的.python式的函数用来处理导航.搜索.修改分析树等 ...

  8. AE开发之txt转shp

    实现坐标txt文件转shp点集数据文件的窗体Form txt格式为:首行为“id,x,y” 第二行开始输入具体数值:id,x,y(x,y为具体的xy坐标) using System; using Sy ...

  9. MySQL新特性文档型数据库

    mongodb在文档型数据库这方面一直做的很好,也发展了很多年,MySQL作为一个比较大众的数据库也慢慢支持了该特性,下面介绍一下MySQL支持文档型数据库的简单操作. 环境: 主机名 IP 系统 软 ...

  10. Mysql表的横向拆分与纵向拆分

    表的拆分分为横向拆分(记录的拆分)和纵向拆分(字段的拆分).拆分表的目的:提高查询速度. 1.横向拆分 我们从一个案例去解释,情景是这样的:某某博客,有50W的博客量,有2w的用户,发现随着用户和博客 ...