bzoj 1593: [Usaco2008 Feb]Hotel [Line segment tree]

Reference: https://blog.csdn.net/u010336344/article/details/53034372
God-like line segment tree
Line segment tree maintenance: ll starts the longest empty segment from the left; rr starts the longest empty segment from the right; the longest empty segment in the len interval Segment; tg: -1 is not all empty, 0 is empty, 1 is full; lz download mark: -1 is not marked, 1 is full, 0 is empty and
modified When modifying to a whole range, change lz and tg, and change ll, rr, len to r-l+1 or 0
, and then when downloading the mark, it is the same as above . When
merging upwards, first change the ll, rr is passed to the current interval, and then ll and rr of the current interval are expanded according to whether the tg of the left and right intervals is 0 (all empty); tg is changed according to the left and right intervals tg; len is from the left interval len, right interval len and left interval rl+right interval When taking the max
query in ll, you can first check the left side, and jump on the tree like a bisection.

#include<iostream>
#include<cstdio>
using namespace std;
const int N=100005;
int n,m;
struct xds
{
    int l,r,ll,rl,tg,len,lz;
}t[N<<1];
int read()
{
    int r=0,f=1;
    char p=getchar();
    while(p>'9'||p<'0')
    {
        if(p=='-')
            f=-1;
        p=getchar();
    }
    while(p>='0'&&p<='9')
    {
        r=r*10+p-48;
        p=getchar();
    }
    return r*f;
}
void pd(int ro)
{
    if(t[ro].lz!=-1)
    {
        if(t[ro].lz==1)
        {
            t[ro<<1].rl=t[ro<<1].ll=t[ro<<1].len=0;
            t[ro<<1|1].rl=t[ro<<1|1].ll=t[ro<<1|1].len=0;
        }
        else
        {
            t[ro<<1].rl=t[ro<<1].ll=t[ro<<1].len=t[ro<<1].r-t[ro<<1].l+1;
            t[ro<<1|1].rl=t[ro<<1|1].ll=t[ro<<1|1].len=t[ro<<1|1].r-t[ro<<1|1].l+1;
        }
        t[ro<<1].tg=t[ro<<1|1].tg=t[ro].tg;
        t[ro<<1].lz=t[ro<<1|1].lz=t[ro].lz;
        t[ro].lz=-1;
    }
}
void ud(int ro)
{
    if(t[ro<<1].tg==t[ro<<1|1].tg)
        t[ro].tg=t[ro<<1].tg;
    else
        t[ro].tg=-1;
    t[ro].ll=t[ro<<1].ll;
    t[ro].rl=t[ro<<1|1].rl;
    if(!t[ro<<1].tg)
        t[ro].ll+=t[ro<<1|1].ll;
    if(!t[ro<<1|1].tg)
        t[ro].rl+=t[ro<<1].rl;
    t[ro].len=max(max(t[ro<<1].len,t[ro<<1|1].len),t[ro<<1].rl+t[ro<<1|1].ll);
}
void build(int ro,int l,int r)
{
    t[ro].l=l,t[ro].r=r,t[ro].len=t[ro].ll=t[ro].rl=r-l+1,t[ro].lz=-1;
    if(l==r)
        return;
    int mid=(l+r)>>1;
    build(ro<<1,l,mid);
    build(ro<<1|1,mid+1,r);
}
void update(int ro,int l,int r,int k)
{
    if(t[ro].l==l&&t[ro].r==r)
    {
        if(k)
            t[ro].rl=t[ro].ll=t[ro].len=0;
        else
            t[ro].rl=t[ro].ll=t[ro].len=r-l+1;
        t[ro].tg=t[ro].lz=k;
        return;
    }
    pd(ro);
    int mid=(t[ro].l+t[ro].r)>>1;
    if(r<=mid)
        update(ro<<1,l,r,k);
    else if(l>mid)
        update(ro<<1|1,l,r,k);
    else
        update(ro<<1,l,mid,k),update(ro<<1|1,mid+1,r,k);
    ud(ro);
}
int ques(int ro,int k)
{
    int re=-1;
    while(t[ro].l&&t[ro].len>=k)
    {
        if(t[ro].ll>=k)
        {
            re=t[ro].l;
            break;
        }
        if(t[ro<<1].len>=k)
            ro<<=1;
        else
        {
            if(t[ro<<1].rl!=0&&t[ro<<1].rl+t[ro<<1|1].ll>=k)
            {
                re=t[ro<<1].r-t[ro<<1].rl+1;
                break;
            }
            else
                ro=ro<<1|1;
        }
    }
    return re;
}
int main()
{
    n=read(),m=read();
    build(1,1,n);
    while(m--)
    {
        int o=read();
        if(o==1)
        {
            int x=read(),now=ques(1,x);
            if(now!=-1)
            {
                printf("%d\n",now);
                update(1,now,now+x-1,1);
            }
            else
                puts("0");
        }
        else
        {
            int x=read(),y=read();
            update(1,x,x+y-1,0);
        }
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325280071&siteId=291194637