HDU 2871 Memory Control

线段树各种操作+STL

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn=50000+10;
struct SegTree
{
    int lsum;
    int rsum;
    int msum;
    int cover;
}segTree[4*maxn];
struct block
{
    int begin, end; 
};
vector<block>v;
int N,Q,x;
char op[10];

bool cmp(const block &a, const block &b)  
{  
    return a.begin < b.begin;  
}  

void pushUp(int rt,int len)
{
    if(segTree[2*rt].lsum==len-len/2)
        segTree[rt].lsum=segTree[2*rt].lsum+segTree[2*rt+1].lsum;
    else segTree[rt].lsum=segTree[2*rt].lsum;

    if(segTree[2*rt+1].rsum==len/2)
        segTree[rt].rsum=segTree[2*rt].rsum+segTree[2*rt+1].rsum;
    else segTree[rt].rsum=segTree[2*rt+1].rsum;

    segTree[rt].msum=max(segTree[2*rt].msum,segTree[2*rt+1].msum);
    segTree[rt].msum=max(segTree[rt].msum,segTree[2*rt+1].lsum+segTree[2*rt].rsum);
}

void pushDown(int rt,int len)
{
    if(segTree[rt].cover!=-1)
    {
        segTree[2*rt].lsum=segTree[2*rt].rsum=segTree[2*rt].msum=(segTree[rt].cover?0:len-len/2);
        segTree[2*rt+1].lsum=segTree[2*rt+1].rsum=segTree[2*rt+1].msum=(segTree[rt].cover?0:len/2);
        segTree[2*rt].cover=segTree[2*rt+1].cover=segTree[rt].cover;
        segTree[rt].cover=-1;
    }
}

void build(int l,int r,int rt)
{
    segTree[rt].lsum=r-l+1;
    segTree[rt].rsum=r-l+1;
    segTree[rt].msum=r-l+1;
    segTree[rt].cover=-1;

    if(l==r) return;

    int m=(l+r)/2;
    build(l,m,2*rt);
    build(m+1,r,2*rt+1);

    pushUp(rt,r-l+1);
}

void Update(int info,int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R)
    {
        segTree[rt].cover=info;
        segTree[rt].lsum=segTree[rt].rsum=segTree[rt].msum=(info?0:r-l+1);
        return;
    }
    pushDown(rt,r-l+1);
    int m=(l+r)/2;
    if(L<=m) Update(info,L,R,l,m,2*rt);
    if(R>=m+1) Update(info,L,R,m+1,r,2*rt+1);
    pushUp(rt,r-l+1);
}

int Quary(int info,int l,int r,int rt)
{
    if(l==r) return l;
    int m=(l+r)/2;
    pushDown(rt,r-l+1);
    if(segTree[2*rt].msum>=info) return Quary(info,l,m,2*rt);
    else if(segTree[2*rt].rsum+segTree[2*rt+1].lsum>=info) return m-segTree[2*rt].rsum+1;
    else if(segTree[2*rt+1].msum>=info) return Quary(info,m+1,r,2*rt+1);
    pushUp(rt,r-l+1);
}

int main()
{
    //freopen("F:\in.txt","r",stdin);
    //freopen("F:\out.txt","w",stdout);

    while(~scanf("%d%d",&N,&Q))
    {
        v.clear();
        build(1,N,1);
        while(Q--)
        {
            scanf("%s",op);
            if(op[0]=='R') 
            {
                Update(0,1,N,1,N,1);
                v.clear(); 
                printf("Reset Now
");
            }

            else if(op[0]=='N')
            {
                scanf("%d",&x);
                if(segTree[1].msum<x) printf("Reject New
");
                else{

                    int pos=Quary(x,1,N,1);
                    printf("New at %d
",pos);

                    block y;  
                    y.begin = pos, y.end = pos + x - 1;  
                    vector<block>::iterator it;  
                    it = upper_bound(v.begin(), v.end(), y, cmp);
                    v.insert(it, y);  

                    Update(1,pos,pos+x-1,1,N,1);
                }
            }

            else if(op[0]=='F')
            {
                scanf("%d", &x);  

                block y;  
                y.begin = x, y.end = x;  
                vector<block>::iterator it;  
                it = upper_bound(v.begin(), v.end(), y, cmp);

                int tmp = it - v.begin() - 1;  
                if (tmp == - 1 || v[tmp].end < x) printf("Reject Free
");  
                else  
                {  
                    printf("Free from %d to %d
", v[tmp].begin, v[tmp].end);  
                    Update(0,v[tmp].begin,v[tmp].end,1,N,1);
                    v.erase(v.begin() + tmp);  
                }  
            }

            else if(op[0]=='G')
            {
                scanf("%d", &x);  
                if (x > v.size()) printf("Reject Get
");  
                else printf("Get at %d
", v[x-1].begin);  
            }
        }
        printf("
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zufezzt/p/5047246.html