HDU-2871-Memory Control

不得不说这个题确实是练习线段树的好题,跟Hotel比较类似,但总体来说要难不少。最开始一直想的记录的问题,后来看到别人用vector才发现这样用使代码好写好多~

多的不说了,看代码吧。其实更新那些都还比较常规,主要是vector的运用。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=6e4;
const int maxm=maxn*3;
struct Node
{
    int l;
    int r;
    int len;
    int res;
    int resl;
    int resr;
    bool isupdate;
}t[maxm];
struct Operation
{
    int begin;
    int end;
    Operation(){}
    Operation(int sbegin,int send)
    {
        begin=sbegin;
        end=send;
    }
    bool operator < (const Operation &a)const
    {
        return begin<a.begin;
    }
};
int n,m;
vector<Operation> oper;
vector<Operation>::iterator it;
void Build(int l,int r,int index)
{
    t[index].l=l;
    t[index].r=r;
    t[index].len=r-l+1;
    t[index].isupdate=false;
    t[index].resl=t[index].resr=t[index].res=t[index].len;
    if(l==r)
        return;
    int mid=(l+r)>>1;
    Build(l,mid,index<<1);
    Build(mid+1,r,index<<1|1);
}
void PushUp(int index)
{
    if(t[index<<1].resl==t[index<<1].len)
        t[index].resl=t[index<<1].len+t[index<<1|1].resl;
    else
        t[index].resl=t[index<<1].resl;
    if(t[index<<1|1].resr==t[index<<1|1].len)
        t[index].resr=t[index<<1|1].len+t[index<<1].resr;
    else
        t[index].resr=t[index<<1|1].resr;
    t[index].res=max(t[index<<1].res,t[index<<1|1].res);
    t[index].res=max(t[index].res,max(t[index].resl,t[index].resr));
    t[index].res=max(t[index].res,t[index<<1].resr+t[index<<1|1].resl);
}
void PushDown(int index)
{
    t[index].isupdate=false;
    if(t[index].l==t[index].r)
        return;
    t[index<<1].isupdate=t[index<<1|1].isupdate=true;
    if(t[index].res==t[index].len)
    {
        t[index<<1].resl=t[index<<1].resr=t[index<<1].res=t[index<<1].len;
        t[index<<1|1].resl=t[index<<1|1].resr=t[index<<1|1].res=t[index<<1|1].len;
    }
    if(!t[index].res)
    {
        t[index<<1].resl=t[index<<1].resr=t[index<<1].res=0;
        t[index<<1|1].resl=t[index<<1|1].resr=t[index<<1|1].res=0;
    }
}
void Update(int l,int r,int index,int val)
{
    if(t[index].isupdate)
        PushDown(index);
    if(t[index].l==l&&t[index].r==r)
    {
        t[index].isupdate=true;
        if(!val)
            t[index].res=t[index].resl=t[index].resr=t[index].len;
        else
            t[index].res=t[index].resl=t[index].resr=0;
        return;
    }
    int mid=(t[index].l+t[index].r)>>1;
    if(r<=mid)
        Update(l,r,index<<1,val);
    else if(l>mid)
        Update(l,r,index<<1|1,val);
    else
    {
        Update(l,mid,index<<1,val);
        Update(mid+1,r,index<<1|1,val);
    }    
    PushUp(index);
}
int Query(int index,int val)
{
    if(t[index].res<val)
        return -1;
    if(t[index].isupdate)
        PushDown(index);
    if(t[index].l==t[index].r)
        return t[index].l;
    if(t[index<<1].res>=val)
        return Query(index<<1,val);
    if(t[index<<1].resr&&t[index<<1].resr+t[index<<1|1].resl>=val)
        return t[index<<1].r-t[index<<1].resr+1;
    return Query(index<<1|1,val);
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        Build(1,n,1);
        oper.clear();
        while(m--)
        {
            char op[20];
            scanf("%s",op);
            if(op[0]=='N')
            {
                //New
                int val;
                scanf("%d",&val);
                int ans=Query(1,val);
                if(ans==-1)
                {
                    printf("Reject New\n");
                    continue;
                }
                else
                    printf("New at %d\n",ans);
                Update(ans,ans+val-1,1,1);
                Operation opt=Operation(ans,ans+val-1);
                it=upper_bound(oper.begin(),oper.end(),opt);
                oper.insert(it,opt);
            }
            else if(op[0]=='F')
            {
                int val;
                scanf("%d",&val);
                Operation opt=Operation(val,val);
                it=upper_bound(oper.begin(),oper.end(),opt);
                int index=it-oper.begin()-1;
                if(index==-1||oper[index].end<val)
                {
                    printf("Reject Free\n");
                    continue;
                }
                printf("Free from %d to %d\n",oper[index].begin,oper[index].end);
                Update(oper[index].begin,oper[index].end,1,0);
                oper.erase(oper.begin()+index);
            }
            else if(op[0]=='G')
            {
                int val;
                scanf("%d",&val);
                if(val>oper.size())
                    printf("Reject Get\n");
                else
                    printf("Get at %d\n",oper[val-1].begin);
            }
            else 
            {
                //Reset
                oper.clear();
                Update(1,n,1,0);
                printf("Reset Now\n");
            }
        }
        printf("\n");
    }
    return 0;
}


你可能感兴趣的:(线段树)