線段樹 HDU 2871 memory control

題目鏈接: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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章