POJ 3667 Hotel

线段树,区间更新

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

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=50000+10;
int lsum[maxn*4],rsum[maxn*4],nsum[maxn*4],mark[maxn*4];
int N,M;
int pos;

void pushup(int node,int len)
{
    if(lsum[node*2]==len-len/2) lsum[node]=lsum[node*2]+lsum[node*2+1];
    else lsum[node]=lsum[node*2];

    if(rsum[node*2+1]==len/2) rsum[node]=rsum[node*2+1]+rsum[node*2];
    else rsum[node]=rsum[node*2+1];

    nsum[node]=max(rsum[node*2]+lsum[node*2+1],max(nsum[node*2],nsum[node*2+1]));
}

void pushdown(int node,int len)
{
    if(mark[node]!=-1)
    {
        mark[node*2]=mark[node*2+1]=mark[node];
        if(mark[node]==1) 
        {
            lsum[node*2]=rsum[node*2]=nsum[node*2]=0;
            lsum[node*2+1]=rsum[node*2+1]=nsum[node*2+1]=0;
        }
        else
        {
            lsum[node*2]=rsum[node*2]=nsum[node*2]=len-len/2;
            lsum[node*2+1]=rsum[node*2+1]=nsum[node*2+1]=len/2;
        }
        mark[node]=-1;
    }
}

void build(int L,int R,int rt)
{
    if(L==R)
    {
        lsum[rt]=rsum[rt]=nsum[rt]=1;
        mark[rt]=-1;
        return;
    }
    int m=(L+R)/2;
    build(L,m,2*rt);
    build(m+1,R,2*rt+1);
    pushup(rt,R-L+1);
}

void query(int x,int l,int r,int rt)
{
    if(l==r) 
    {
        pos=l;
        return;
    }
    pushdown(rt,r-l+1);
    int m=(l+r)/2;
    if(x<=nsum[rt*2]) query(x,l,m,rt*2);
    else if(x<=rsum[rt*2]+lsum[rt*2+1]) pos=m-rsum[rt*2]+1;
    else query(x,m+1,r,rt*2+1);
    if(pos!=-1) return;
}

void update(int L,int R,int c,int l,int r,int rt)
{
    if(L<=l&&R>=r)
    {
        if(c==1) nsum[rt]=lsum[rt]=rsum[rt]=0;
        else nsum[rt]=lsum[rt]=rsum[rt]=r-l+1;
        mark[rt]=c;
        return;
    }

    pushdown(rt,r-l+1);

    int m=(l+r)/2;
    if(L<=m) update(L,R,c,l,m,2*rt);
    if(R>=m+1) update(L,R,c,m+1,r,2*rt+1);

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

int main()
{
    while(~scanf("%d%d",&N,&M))
    {
        build(1,N,1);
        while(M--)
        {
            int op,a,b;
            scanf("%d",&op);
            if(op==1)
            {
                scanf("%d",&a);
                if(nsum[1]<a) printf("0
");
                else
                {
                    pos=-1;
                    query(a,1,N,1);
                    printf("%d
",pos);
                    update(pos,pos+a-1,1,1,N,1);
                }
            }
            else
            {
                scanf("%d%d",&a,&b);
                update(a,a+b-1,0,1,N,1);
            }
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zufezzt/p/4997435.html