您的位置:首页 > 其它

线段树 HDU 2871 memory control

2012-08-30 21:03 92 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2871

代码风格:http://www.notonlysuccess.com/index.php/segment-tree-complete/

题目大意:一段内存条,new k表示要要申请k个位置的空内存,free k表示要释放第k个位置的内存及与k位置内存相关的内存,get k表示要获得从内存条左到右第k段内存输出左端点,reset表示释放整段内存

算法:线段树,STL(vector)

思路:new覆盖有空的位置,并记录下申请到内存的左边位置和右边位置

free时,找到那个内存位置的左端点和右端点,并且取消覆盖

get k时,如果v.size() < k,输出reject ,否则直接输出左端点v[k-1].l

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;

#define lson l, m, rt << 1
#define rson m+1, r, rt << 1 |1
#define mid int m = (l + r) >> 1

struct Seg
{
int l, r;
}p;
const int Max = 50010;
int lsum[Max << 2], rsum[Max << 2], msum[Max << 2], cover[Max << 2];
vector<Seg> v;
vector<Seg>::iterator it;

int maxz(int a, int b)
{
return a > b? a : b;
}

void PushUp(int rt, int m)
{
lsum[rt] = lsum[rt << 1];
rsum[rt] = rsum[rt << 1 | 1];
if(lsum[rt] == m - (m >> 1))
lsum[rt] += lsum[rt << 1 | 1];
if(rsum[rt] == m >> 1)
rsum[rt] += rsum[rt << 1];
msum[rt] = maxz(maxz(msum[rt << 1], msum[rt << 1 | 1]), lsum[rt << 1 | 1] + rsum[rt << 1]);
}

void PushDown(int rt, int m)
{
if(cover[rt] != -1)
{
cover[rt << 1] = cover[rt << 1 | 1] = cover[rt];
msum[rt << 1] = lsum[rt << 1] = rsum[rt << 1] = cover[rt] ? 0 : m - (m >> 1);
msum[rt << 1 | 1] = lsum[rt << 1 | 1] = rsum[rt << 1 | 1] = cover[rt] ? 0 : m >> 1;
cover[rt] = -1;
}
}
void build(int l, int r, int rt)
{
if(l == r)
{
msum[rt] = rsum[rt] = lsum[rt] = 1;
return ;
}
mid ;
build(lson);
build(rson);
PushUp(rt, r-l+1);
}

void update(int L, int R, int k, int l, int r, int rt)
{
if(L <= l && r <= R)
{
cover[rt] = k;
msum[rt] = rsum[rt] = lsum[rt] = k ? 0 : r-l+1;
return ;
}
mid ;
PushDown(rt, r-l+1);
if(L <= m)
update(L, R, k, lson);
if(m < R)
update(L, R, k, rson);
PushUp(rt, r-l+1);
}

int query(int k, int l, int r, int rt)
{
if(l == r)
{
return l;
}
mid ;
PushDown(rt, r-l+1);
if(k <= msum[rt << 1])
return query(k, lson);
else if(k <= lsum[rt << 1 | 1] + rsum[rt << 1])
return m - rsum[rt << 1] + 1;
else
return query(k, rson);
}

bool cmp(const Seg &a, const Seg &b)
{
return a.l < b.l ;
}

int main()
{
int n, m;
char op[15];
int a;
while(scanf("%d%d", &n, &m) != EOF)
{
build(1, n, 1);
v.clear();
memset(cover, -1, sizeof(cover));
while(m --)
{
scanf("%s", op);
if(op[0] == 'R')
{
update(1, n, 0, 1, n, 1);
v.clear();
printf("Reset Now\n");
}
else if(op[0] == 'N')
{
scanf("%d", &a);
if(msum[1] < a)
{
printf("Reject New\n");
}
else
{
int k = query(a, 1, n, 1);
printf("New at %d\n", k);
p.l = k;
p.r = k+a-1;
update(p.l, p.r, 1, 1, n, 1);
it = upper_bound(v.begin(), v.end(), p, cmp);
v.insert(it, p);
}
}
else if(op[0] == 'F')
{
scanf("%d", &a);
p.l = a; p.r = a;
it = upper_bound(v.begin(), v.end(), p, cmp);
int temp = it - v.begin() - 1;
if(temp == -1 || v[temp].r < a)
{
printf("Reject Free\n");
}
else
{
update(v[temp].l, v[temp].r, 0, 1, n, 1);
printf("Free from %d to %d\n", v[temp].l, v[temp].r);
v.erase(v.begin()+temp);
}
}
else
{
scanf("%d", &a);
if(v.size() < a)
{
printf("Reject Get\n");
}
else
{
printf("Get at %d\n", v[a-1].l);
}
}
}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: