hdu 2871 线段树 成段更新+STL

/*
分析本题和我前几天做的题目非常类似,但模拟过程需要用vector 来处理。。。貌似我又弱在了这个stl 身上了。。整了2个小时的stl.........
题目分析:题目有4个操作:Reset指清空整个线段树,即题目所说的清空整个内存块;
New N就是申请N个最靠左边的连续内存块,
Free x操作是释放包含x的连续内存块,
Get x,就是获得第x个内存块的起始节点
我们用vector存取所有申请过的空间,删除所有释放的空间,查询第n个区间也是非常easy。
关键在于vector可以在中间进行查询,增减!!这也是该题所要求的一个一个知识点。
还是对stl 不熟

*/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
using namespace std;
const int maxn=55555;
int lmax[maxn<<2],rmax[maxn<<2],mmax[maxn<<2],col[maxn<<2],n,m;
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
char op[10];
struct node///优先队列
{
    int l,r;
    bool operator < (const node &cmp) const
    {
        return l<cmp.l;
    }
} ;
void pushup(int rt,int l,int r)
{
    int mid=(l+r)>>1;
    lmax[rt]=lmax[rt<<1];
    rmax[rt]=rmax[rt<<1|1];
    mmax[rt]=max(rmax[rt<<1]+lmax[rt<<1|1],max(mmax[rt<<1],mmax[rt<<1|1]));
    if(lmax[rt<<1]==mid-l+1) lmax[rt]+=lmax[rt<<1|1];
    if(rmax[rt<<1|1]==r-mid) rmax[rt]+=rmax[rt<<1];
}
void build(int rt,int l,int r)
{
    lmax[rt]=rmax[rt]=mmax[rt]=(r-l+1);
    col[rt]=-1;
    if(l==r)return;
    int mid=(l+r)>>1;
    build(lson);
    build(rson);
    pushup(rt,l,r);
}
void pushdown(int rt,int l,int r)
{
    if(col[rt]!=-1)
    {
        col[rt<<1]=col[rt<<1|1]=col[rt];
        int mid=(l+r)>>1;
        if(col[rt]==1)///已被占用
        {
            lmax[rt<<1]=rmax[rt<<1]=lmax[rt<<1|1]=rmax[rt<<1|1]=mmax[rt<<1]=mmax[rt<<1|1]=0;
        }
        else
        {
            lmax[rt<<1]=rmax[rt<<1]=mmax[rt<<1]=mid-l+1;
            lmax[rt<<1|1]=rmax[rt<<1|1]=mmax[rt<<1|1]=r-mid;
        }
        col[rt]=-1;
    }
}
void updata(int rt,int l,int r,int L,int R,int val)
{
    if(L<=l&&r<=R)
    {
        col[rt]=val;
        lmax[rt]=rmax[rt]=mmax[rt]=(r-l+1)*(val^1);
        return ;
    }
    pushdown(rt,l,r);
    int mid=(l+r)>>1;
    if(mid>=L)updata(lson,L,R,val);
    if(mid<R)updata(rson,L,R,val);
    pushup(rt,l,r);
}
int query(int rt,int l,int r,int len)
{
    if(mmax[rt]<len) return -1;
    if(lmax[rt]>=len)return l;
    pushdown(rt,l,r);
    int mid=(l+r)>>1;
    if(mmax[rt<<1]>=len)return query(lson,len);
    if(rmax[rt<<1]+lmax[rt<<1|1]>=len) return mid-rmax[rt<<1]+1;
    return query(rson,len);
}
int main()
{
    int i,j,res,tmp;
    char s[10];
    vector<node>V;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        build(1,1,n);
        V.clear();
        while(m--)
        {
            scanf("%s",s);
            if(s[0] == 'N')
            {
                scanf("%d",&res);
                if(mmax[1] < res)
                    puts("Reject New");
                else
                {
                    int ret= query(1,1,n,res);
                    printf("New at %d\n",ret);
                    updata(1,1,n,ret,ret+res-1,1);
                    node p;
                    p.l = ret;
                    p.r = ret+res-1;
                    vector<node>::iterator it;
                    it = upper_bound(V.begin(),V.end(),p);
                    V.insert(it,p);
                }
            }
            else if(s[0] == 'F')
            {
                scanf("%d",&res);
                node p;
                p.l = res;
                p.r = res;
                vector<node>::iterator it;
                it = upper_bound(V.begin(),V.end(),p);
                int tmp = it - V.begin() - 1;
                if(tmp == -1 || V[tmp].r<res)
                    puts("Reject Free");
                else
                {
                    printf("Free from %d to %d\n", V[tmp].l, V[tmp].r);
                    updata(1,1,n,V[tmp].l,V[tmp].r,0);
                    V.erase(V.begin()+tmp);
                }
            }
            else if(s[0] == 'G')
            {
                scanf("%d",&res);
                if(res > V.size())
                    puts("Reject Get");
                else
                    printf("Get at %d\n",V[res-1].l);
            }
            else if(s[0] == 'R')
            {
                updata(1,1,n,1,n,0);
                V.clear();
                puts("Reset Now");
            }
        }
        printf("\n");
    }
    return 0;
}


/*
6 16
New 2
New 5
New 2
New 2
Free 3
Get 1
Get 2
Get 3
Free 3
Reset
New 2
New 5
New 2
New 2
*/

你可能感兴趣的:(hdu 2871 线段树 成段更新+STL)