热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

HDU2871内存管理问题(线段树优化)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2871。本题涉及内存管理操作,包括重置、申请、释放和查询内存块。通过使用线段树进行高效管理和维护。

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


题意描述:给定一段内存空间,支持以下四种操作:



  • Reset:重置所有内存。

  • New x:申请一块大小为x的内存,返回最左边可用的起始地址。

  • Free x:释放包含地址x的内存块。

  • Get x:获取第x块内存的首地址。


解题思路:此题需要处理复杂的内存分配与释放操作,线段树是一种有效的数据结构选择。为了方便处理free和get操作,可以结合Vector来辅助实现。线段树主要负责维护内存的连续长度和最大连续长度。


具体实现中,ll[rt]表示该区段从左开始的连续内存长度,rr[rt]表示从右开始的连续内存长度,mlen[rt]表示该区间内的最大连续内存长度。这样的维护方式能够确保在线段树中任意操作区间的高效性。



#include 
#include
#include
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 };

const int maxn = 50010;
int n, m, num, ll[maxn <<2], rr[maxn <<2], lazy[maxn <<2], mlen[maxn <<2];
vector Q;

inline void pup(int l, int r, int rt) {
int m = (l + r) >> 1;
mlen[rt] = Max(mlen[rt <<1], mlen[rt <<1 | 1]);
mlen[rt] = Max(mlen[rt], rr[rt <<1] + ll[rt <<1 | 1]);
ll[rt] = ll[rt <<1] + (ll[rt <<1] == m - l + 1 ? ll[rt <<1 | 1] : 0);
rr[rt] = rr[rt <<1 | 1] + (rr[rt <<1 | 1] == r - m ? rr[rt <<1] : 0);
}

inline void pdown(int l, int r, int rt) {
if (lazy[rt] != -1) {
lazy[rt <<1] = lazy[rt <<1 | 1] = lazy[rt];
int m = (l + r) >> 1;
mlen[rt <<1] = ll[rt <<1] = rr[rt <<1] = (lazy[rt] == 0 ? m - l + 1 : 0);
mlen[rt <<1 | 1] = rr[rt <<1 | 1] = ll[rt <<1 | 1] = (lazy[rt] == 0 ? r - m : 0);
lazy[rt] = -1;
}
}

int New(int l, int r, int rt, int num) {
if (l == r) return l;
int m = (l + r) >> 1;
pdown(l, r, rt);
if (mlen[rt <<1] >= num) return New(ls, num);
else if (rr[rt <<1] + ll[rt <<1 | 1] >= num) return m - rr[rt <<1] + 1;
else return New(rs, num);
}

void covr(int op, int L, int R, int l, int r, int rt) {
if (L <= l && r <= R) {
lazy[rt] = op;
ll[rt] = rr[rt] = mlen[rt] = (op == 0 ? r - l + 1 : 0);
return;
}
pdown(l, r, rt);
int m = (l + r) >> 1;
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(edge{0, 0});
Q.push_back(edge{100000, 100000});
covr(0, 1, 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[20];
edge s = {0, 0}, e = {100000, 100000};
while (~scanf("%d%d", &n, &m)) {
reset();
while (m--) {
scanf("%s", op);
if (op[0] != 'R') scanf("%d", &num);
if (op[0] == 'N') {
if (mlen[1] else {
int x = New(root, num);
printf("New at %d\n", x);
edge tp = {x, x + num - 1};
covr(1, tp.l, tp.r, root);
insert(tp);
}
} else if (op[0] == 'F') {
edge tp = {num, num};
int now = upper_bound(Q.begin(), Q.end(), tp) - Q.begin() - 1;
if (Q[now].l <= num && Q[now].r >= num) {
covr(0, 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[0] == 'G') {
if (num > Q.size() - 2) puts("Reject Get");
else printf("Get at %d\n", Q[num].l);
} else {
reset();
puts("Reset Now");
}
}
puts("");
}
return 0;
}


推荐阅读
author-avatar
手机用户2502853447_666
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有