hdu 2871 Memory Control(线段树)

本文深入探讨了vector数据结构的特点,将其比喻为数组式链表,并展示了如何利用vector维护区间信息。通过实践代码,学习了vector的erase、insert应用及区间查询优化技巧。

重新认识vector - -其实就是链表式数组,或者说数组式链表?  哈哈哈

其实还是跟 Hotel 一样,然后加了Get操作吧。

用vector维护一下有多少个区间嘛。

也学会了vector 的erase和insert的应用。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <set>
#include <vector>
#define lson num<<1,s,mid
#define rson num<<1|1,mid+1,e
#define maxn 50005
using namespace std;

int cov[maxn<<2];
int rmax[maxn<<2];
int lmax[maxn<<2];
int cmax[maxn<<2];

struct node
{
    int st,ed;
};
vector<node>cq;
void pushup(int num,int s,int e)
{
    int mid=(s+e)>>1;
    cmax[num]=max(rmax[num<<1]+lmax[num<<1|1],max(cmax[num<<1],cmax[num<<1|1]));
    lmax[num]=lmax[num<<1];
    rmax[num]=rmax[num<<1|1];
    if(lmax[num]==mid-s+1)lmax[num]+=lmax[num<<1|1];
    if(rmax[num]==e-mid)rmax[num]+=rmax[num<<1];
}
void pushdown(int num,int s,int e)
{
    if(cov[num]!=-1)
    {
        int mid=(s+e)>>1;
        cov[num<<1]=cov[num<<1|1]=cov[num];
        cmax[num<<1]=lmax[num<<1]=rmax[num<<1]=cov[num]?0:mid-s+1;
        cmax[num<<1|1]=lmax[num<<1|1]=rmax[num<<1|1]=cov[num]?0:e-mid;
        cov[num]=-1;
    }
}
void build(int num,int s,int e)
{
    cov[num]=-1;
    if(s==e)
    {
        lmax[num]=rmax[num]=cmax[num]=1;
        return;
    }
    int mid=(s+e)>>1;
    build(lson);
    build(rson);
    pushup(num,s,e);
}
void update(int num,int s,int e,int l,int r,int val)
{
    if(l<=s && r>=e)
    {
        cov[num]=val;
        lmax[num]=rmax[num]=cmax[num]=val?0:e-s+1;
        return;
    }
    pushdown(num,s,e);
    int mid=(s+e)>>1;
    if(l<=mid)update(lson,l,r,val);
    if(r>mid)update(rson,l,r,val);
    pushup(num,s,e);
}
int query(int num,int s,int e,int val)
{
    if(s==e)
    {
        return s;
    }
    pushdown(num,s,e);
    int mid=(s+e)>>1;
    if(cmax[num<<1]>=val)return query(lson,val);
    else if(rmax[num<<1]+lmax[num<<1|1]>=val)return mid+1-rmax[num<<1];
    else return query(rson,val);
}
int bin(int key)
{
    int l=0,r=cq.size()-1;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(cq[mid].st<=key)l=mid+1;
        else r=mid-1;
    }
    return l-1;
}
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        cq.clear();
        build(1,1,n);
        while(m--)
        {
            char str[10];
            scanf("%s",str);
            if(str[0]=='R')
            {
                cq.clear();
                update(1,1,n,1,n,0);
                printf("Reset Now\n");
            }
            else if(str[0]=='N')
            {
                int v;
                scanf("%d",&v);
                if(cmax[1]<v)printf("Reject New\n");
                else
                {
                    int L=query(1,1,n,v);
                    update(1,1,n,L,L+v-1,1);
                    node buf;
                    buf.st=L;
                    buf.ed=L+v-1;
                    int index=bin(L)+1;
                    cq.insert(cq.begin()+index,buf);
                    printf("New at %d\n",L);
                }
            }
            else if(str[0]=='F')
            {
                int v;
                scanf("%d",&v);
                int index=bin(v);
                if(index==-1||cq[index].ed<v)
                {
                    printf("Reject Free\n");
                }
                else
                {
                    int l=cq[index].st;
                    int r=cq[index].ed;
                    update(1,1,n,l,r,0);
                    printf("Free from %d to %d\n",cq[index].st,cq[index].ed);
                    cq.erase(cq.begin()+index,cq.begin()+index+1);
                }
            }
            else
            {
                int v;
                scanf("%d",&v);
                if(cq.size()<v)
                printf("Reject Get\n");
                else {
                    printf("Get at %d\n",cq[v-1].st);
                }
            }
        }
        puts("");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值