[BZOJ4592][SHOI2015]脑洞治疗仪

Posted 租酥雨

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BZOJ4592][SHOI2015]脑洞治疗仪相关的知识,希望对你有一定的参考价值。

bzoj
luogu
题意:给你一段01序列,要求支持如下操作:(下面把正常脑区域视为0,脑洞视为1)
1、把一段区间全部改成1.
2、把一段区间全部的0挖出来(然后这个区间也就全部变成了1),把这些0放到另一个区间上的1位置,原本的0位置不需要再放,如果0不够就优先放前面。
3、求最大连续1的和。

sol

线段树基本操作。
维护每个区间的和、最大连续段长度、左边最大连续段长度、右边最大连续段长度、是否全是1.
都是基本操作。一边A

code

#include<cstdio>
#include<algorithm>
using namespace std;
int gi()
{
    int x=0,w=1;char ch=getchar();
    while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if (ch=='-') w=0,ch=getchar();
    while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return w?x:-x;
}
const int N = 2e5+5;
struct Data{int sum,mx,ml,mr,ful;}t[N<<2];
Data operator + (Data a,Data b)
{
    Data c;
    c.sum=a.sum+b.sum;
    c.mx=max(max(a.mx,b.mx),a.mr+b.ml);
    c.ml=a.ful?a.sum+b.ml:a.ml;
    c.mr=b.ful?b.sum+a.mr:b.mr;
    c.ful=a.ful&b.ful;
    return c;
}
int n,m,tag[N<<2],Sum;
void build(int x,int l,int r)
{
    tag[x]=-1;
    if (l==r) return;
    int mid=l+r>>1;
    build(x<<1,l,mid);build(x<<1|1,mid+1,r);
    t[x]=t[x<<1]+t[x<<1|1];
}
void cover(int x,int l,int r,int c)
{
    if (c)
    {
        t[x].sum=t[x].mx=t[x].ml=t[x].mr=r-l+1;t[x].ful=1;
        tag[x]=1;
    }
    else
    {
        t[x].sum=t[x].mx=t[x].ml=t[x].mr=t[x].ful=0;
        tag[x]=0;
    }
}
void pushdown(int x,int l,int r)
{
    if (tag[x]!=-1)
    {
        int mid=l+r>>1;
        cover(x<<1,l,mid,tag[x]);cover(x<<1|1,mid+1,r,tag[x]);
        tag[x]=-1;
    }
}
void add(int x,int l,int r,int ql,int qr)
{
    if (l>=ql&&r<=qr) {cover(x,l,r,1);return;}
    pushdown(x,l,r);int mid=l+r>>1;
    if (ql<=mid) add(x<<1,l,mid,ql,qr);
    if (qr>mid) add(x<<1|1,mid+1,r,ql,qr);
    t[x]=t[x<<1]+t[x<<1|1];
}
void del(int x,int l,int r,int ql,int qr)
{
    if (!Sum) return;
    if (l>=ql&&r<=qr&&Sum>=t[x].sum)
    {
        Sum-=t[x].sum;cover(x,l,r,0);
        return;
    }
    pushdown(x,l,r);int mid=l+r>>1;
    if (ql<=mid) del(x<<1,l,mid,ql,qr);
    if (qr>mid) del(x<<1|1,mid+1,r,ql,qr);
    t[x]=t[x<<1]+t[x<<1|1];
}
Data query(int x,int l,int r,int ql,int qr)
{
    if (l>=ql&&r<=qr) return t[x];
    pushdown(x,l,r);int mid=l+r>>1;
    if (qr<=mid) return query(x<<1,l,mid,ql,qr);
    if (ql>mid) return query(x<<1|1,mid+1,r,ql,qr);
    return query(x<<1,l,mid,ql,qr)+query(x<<1|1,mid+1,r,ql,qr);
}
int main()
{
    n=gi();m=gi();build(1,1,n);
    while (m--)
    {
        int opt=gi();
        if (!opt)
        {
            int l=gi(),r=gi();
            add(1,1,n,l,r);
        }
        if (opt==1)
        {
            int l=gi(),r=gi();
            Sum=r-l+1-query(1,1,n,l,r).sum;
            add(1,1,n,l,r);
            l=gi(),r=gi();
            del(1,1,n,l,r);
        }
        if (opt==2)
        {
            int l=gi(),r=gi();
            printf("%d\n",query(1,1,n,l,r).mx);
        }
    }
    return 0;
}

以上是关于[BZOJ4592][SHOI2015]脑洞治疗仪的主要内容,如果未能解决你的问题,请参考以下文章

[bzoj4592] [Shoi2015]脑洞治疗仪

[BZOJ4592][SHOI2015]脑洞治疗仪

BZOJ-4592脑洞治疗仪 线段树

[SHOI 2015] 脑洞治疗仪

BZOJ 4592 脑洞治疗仪

LOJ #2037. 「SHOI2015」脑洞治疗仪