洛谷 P2894 [USACO08FEB]酒店

题目描述

用线段树维护三个值:区间最长空位长度,从左端点可以延伸的最长空位长度,从右端点可以延伸的最长空位长度。

#include<complex>
#include<cstdio>
using namespace std;
const int N=2e6+7;
int n,m;
int len[N],Max[N],maxl[N],maxr[N],lazy[N];
int qread()
{
    int x=0;
    char ch=getchar();
    while(ch<'0' || ch>'9')ch=getchar();
    while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x;
}
void PushUp(int rt)
{
    if(Max[rt<<1]==len[rt<<1])maxl[rt]=Max[rt<<1]+maxl[rt<<1|1];
    else maxl[rt]=maxl[rt<<1];
    if(Max[rt<<1|1]==len[rt<<1|1])maxr[rt]=Max[rt<<1|1]+maxr[rt<<1];
    else maxr[rt]=maxr[rt<<1|1];
    Max[rt]=max(max(Max[rt<<1],Max[rt<<1|1]),maxr[rt<<1]+maxl[rt<<1|1]);
}
void PushDown(int rt)
{
    if(!lazy[rt])return;
    lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt];
    if(lazy[rt]==1)
    {
        Max[rt<<1]=maxl[rt<<1]=maxr[rt<<1]=0;
        Max[rt<<1|1]=maxl[rt<<1|1]=maxr[rt<<1|1]=0;
    }
    else
    {
        Max[rt<<1]=maxl[rt<<1]=maxr[rt<<1]=len[rt<<1];
        Max[rt<<1|1]=maxl[rt<<1|1]=maxr[rt<<1|1]=len[rt<<1|1];
    }
    lazy[rt]=0;
}
void Build(int l,int r,int rt)
{
    maxl[rt]=maxr[rt]=Max[rt]=len[rt]=r-l+1;
    if(l==r)return;
    int mid=l+r>>1;
    Build(l,mid,rt<<1);Build(mid+1,r,rt<<1|1);
}
void Modify(int l,int r,int rt,int nowl,int nowr,int v)
{
    if(nowl<=l && r<=nowr)
    {
        if(v==1)Max[rt]=maxl[rt]=maxr[rt]=0;
        else Max[rt]=maxl[rt]=maxr[rt]=len[rt];
        lazy[rt]=v;
        return;
    }
    PushDown(rt);
    int mid=l+r>>1;
    if(nowl<=mid)Modify(l,mid,rt<<1,nowl,nowr,v);
    if(mid<nowr)Modify(mid+1,r,rt<<1|1,nowl,nowr,v);
    PushUp(rt);
}
int Query(int l,int r,int rt,int p)
{
    if(l==r)return l;
    PushDown(rt);
    int mid=l+r>>1;
    if(Max[rt<<1]>=p)return Query(l,mid,rt<<1,p);
    if(maxr[rt<<1]+maxl[rt<<1|1]>=p)return mid-maxr[rt<<1]+1;
    return Query(mid+1,r,rt<<1|1,p);
}
int main()
{
    scanf("%d%d",&n,&m);
    Build(1,n,1);
    int p,l,r,x;
    while(m--)
    {
        p=qread();
        if(p==1)
        {
            x=qread();
            if(Max[1]<x){puts("0");continue;}
            int tot=Query(1,n,1,x);
            printf("%d\n",tot);
            Modify(1,n,1,tot,tot+x-1,1);
        }
        else
        {
            l=qread();r=qread();
            Modify(1,n,1,l,l+r-1,2);
        }
    }
    return 0;
}

 

posted @ 2018-04-10 11:12  LeTri  阅读(130)  评论(0编辑  收藏  举报