hdu 2871 vector + 线段树 Memory Control

本文介绍了一种结合线段树和Vector的数据结构解决方案,用于处理内存块分配和释放的操作问题。通过具体实现细节和代码示例,展示了如何高效地进行内存管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:
现在有1到N(N <= 50000)个连续内存块,然后给出四种操作:
1. Reset 释放所有内存块,并且输出“Reset Now”。
2. New x 找到一块有连续x块内存的空间,并且占据它。如果有多种,选择起始数字
最小的,然后“New at A”,A表示起始数字;否则输出“Reject New”。
3. Free x 释放一块占据x单元的内存块,并且输出“Free from A to B”,A到B表示
占据的内存块;否则输出“Reject Free”。
4. Get x 找到第x块连续内存,如果找到,输出“Get at A”,A表示起始的数字单元

,如果当前内存块小于x,则输出“Reject Get”。

解:

      用线段树和vector共同完成几个操作。不会vector的伤不起啊。记得上到网赛的cf85d就是找了个vector过的。恩,学。

线段树节点lsum,rsum,msum,cover,就是往常的意思。

做题过程:

       貌似这题做了很久额。中间掺了网络赛和别的东西,再加上我昨天又睡得很晚,今天就废了。

       有时候很奇怪,找一个东西,找很久都没有找到。比如说错误和一些东西。但是,我重新打一遍,就过了。

       build a stone wall and do not fear.

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <set>
#include <vector>
#include <algorithm>
#define lson l,m , rt << 1
#define rson m + 1,r , rt << 1 | 1
#define maxn 50010
#define ls rt << 1
#define rs rt << 1 | 1
#define havem int m = (l + r) >> 1
using namespace std;
int a, b;
int lsum[maxn << 2],rsum[maxn << 2], msum[maxn << 2],cover[maxn << 2],x,n,m;
char op[10];
struct Node{
    int st, end;
};
vector <Node> vec;
void build(int l, int r, int rt){
    rsum[rt] = lsum[rt] = msum[rt] = r - l + 1;
    cover[rt] = 0;
    if(l == r) return ; havem;
    build(lson);  build(rson);
}
void push_dn(int rt, int m){
    if(cover[rt] != -1){
        cover[ls] = cover[rs] = cover[rt];
        if(cover[rt] == 0){
            lsum[ls] = rsum[ls] = msum[ls] = m - (m >> 1);
            lsum[rs] = rsum[rs] = msum[rs] = (m >> 1);
        }else{
            lsum[ls] = rsum[ls] = msum[ls] = 0;
            lsum[rs] = rsum[rs] = msum[rs] = 0;
        }
        cover[rt] = -1;
    }
}
int query(int len, int l, int r, int rt){
    if(l == r) {
            return l;
    }push_dn(rt, r - l + 1); havem;
    if(msum[ls] >= len) return query(len,lson);
    if(rsum[ls] + lsum[rs] >= len) return (m - rsum[ls] + 1);
//    if(msum[rs] >= len)  这句话可以不要
        return query(len,rson);
//    return 0;
}
void push_up(int rt, int m){
    lsum[rt] = lsum[ls];
    rsum[rt] = rsum[rs];
    msum[rt] = max (max(msum[ls],msum[rs]), rsum[ls] + lsum[rs]);
    if(lsum[ls] == (m - (m >> 1))) lsum[rt] += lsum[rs];
    if(rsum[rs] == (m >> 1)) rsum[rt] += rsum[ls];
    if(cover[ls] == cover[rs]) cover[rt]  = cover[ls];
}
void update(int L, int R, int cc, int l , int r, int rt){
    if(L == l && r == R){
        cover[rt] = cc;
        lsum[rt] = rsum[rt] = msum[rt] = (cc == 0? r - l + 1:0);
        return ;
    }push_dn(rt, r - l + 1);
    havem;
    if(R <= m) update(L,R,cc,lson);
    else if(L > m) update(L,R,cc,rson);
    else update(L,m,cc,lson), update(m+ 1, R,cc,rson);
    push_up(rt, r - l + 1);
}
bool cmp(const Node& b1, const Node& b2){
    return b1.st < b2.st;
}
int main(){
    char op[10];
    while(scanf("%d%d",&n,&m) != EOF){
        build(1,n,1);
        vec.clear();
        while(m --){
            scanf("%s",op);
            if(op[0] == 'R'){
                printf("Reset Now\n");
                update(1,n,0,1,n,1);
                vec.clear();
            }else if(op[0] == 'N'){
                scanf("%d",&a);
                if(msum[1] < a)
                    printf("Reject New\n");
                else{
                    b = query(a,1,n,1);
                    printf("New at %d\n",b);
                    update(b, b + a- 1,1, 1, n, 1);
                    Node tmp;
                    tmp.st = b; tmp.end = b + a - 1;
                    if(vec.size() == 0)
                        vec.push_back(tmp);
                    else {
                        vector <Node > ::iterator it;
                        it = upper_bound(vec.begin(),vec.end(),tmp,cmp);
                        vec.insert(it,tmp);
                    }
                }
            }else if(op[0] == 'F'){
                scanf("%d",&a);
                Node tmp;
                tmp.st = a; tmp.end = a;
                vector<Node> ::iterator it;
                it = upper_bound(vec.begin(),vec.end(),tmp,cmp);
                if(it == vec.begin() || (--it)->end < a)
                    printf("Reject Free\n");
                else {
                    printf("Free from %d to %d\n",it ->st, it->end);
                    update(it ->st, it -> end, 0, 1,n,1);
                    vec.erase(it);
                }
            }else{
                scanf("%d",&a);
                if(vec.size() < a)
                    printf("Reject Get\n");
                else
                    printf("Get at %d\n",vec[a - 1].st);
            }
        }
        printf("\n");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值