bzoj千题计划280:bzoj4592: [Shoi2015]脑洞治疗仪

http://www.lydsy.com/JudgeOnline/problem.php?id=4592

注意操作1 先挖再补,就是补的范围可以包含挖的范围

SHOI2015 的题 略水啊(逃)

#include<cstdio>
#include<iostream>

#define N 200001

using namespace std;

#define max(x,y) ((x)>(y) ? (x) : (y))
#define min(x,y) ((x)<(y) ? (x) : (y))

struct node
{
    int L0,R0,mx0;
    int siz;
    
    node operator + (node p) const
    {
        node A;
        A.L0=L0;
        if(L0==siz) A.L0+=p.L0;
        A.R0=p.R0;
        if(p.R0==p.siz) A.R0+=R0;
        A.mx0=max(mx0,p.mx0);
        A.mx0=max(A.mx0,R0+p.L0);
        A.siz=siz+p.siz;
        return A;
    }
    
}tr[N<<2];

int sum1[N<<2];
int tag[N<<2];

int tot;

int n;

void read(int &x)
{
    x=0; char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
}

void build(int k,int l,int r)
{
    tag[k]=-1; 
    tr[k].L0=tr[k].R0=tr[k].mx0=0;
    tr[k].siz=sum1[k]=r-l+1;
    if(l==r) return;
    int mid=l+r>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
}

void tagging(int k,int w)
{
    if(w) sum1[k]=tr[k].siz,tr[k].L0=tr[k].R0=tr[k].mx0=0;
    else sum1[k]=0,tr[k].L0=tr[k].R0=tr[k].mx0=tr[k].siz;
    tag[k]=w;
}

void down(int k)
{
    tagging(k<<1,tag[k]);
    tagging(k<<1|1,tag[k]);
    tag[k]=-1;
}

void change(int k,int l,int r,int opl,int opr,int w)
{
    if(l>=opl && r<=opr)
    {
        tagging(k,w);
        return;
    }
    if(tag[k]!=-1) down(k);
    int mid=l+r>>1;
    if(opl<=mid) change(k<<1,l,mid,opl,opr,w);
    if(opr>mid) change(k<<1|1,mid+1,r,opl,opr,w);
    sum1[k]=sum1[k<<1]+sum1[k<<1|1];
    tr[k]=tr[k<<1]+tr[k<<1|1];
}

void query(int k,int l,int r,int opl,int opr,int w)
{
    if(l>=opl && r<=opr)
    {
        if(w) tot+=sum1[k];
        else tot+=tr[k].siz-sum1[k];
        return;
    }
    if(tag[k]!=-1) down(k);
    int mid=l+r>>1;
    if(opl<=mid) query(k<<1,l,mid,opl,opr,w);
    if(opr>mid) query(k<<1|1,mid+1,r,opl,opr,w);
}

int find(int L,int cnt)
{
    int R=L,mid;
    int l=L,r=n;
    while(l<=r)
    {
        mid=l+r>>1;
        tot=0;
        query(1,1,n,L,mid,0);
        if(tot<=cnt) l=mid+1,R=mid;
        else r=mid-1;
    }
    return R;
}

node Query(int k,int l,int r,int opl,int opr)
{
    if(l==opl && r==opr) return tr[k];
    if(tag[k]!=-1) down(k);
    int mid=l+r>>1;
    if(opr<=mid) return Query(k<<1,l,mid,opl,opr);
    if(opl>mid) return Query(k<<1|1,mid+1,r,opl,opr);
    return Query(k<<1,l,mid,opl,mid)+Query(k<<1|1,mid+1,r,mid+1,opr);
}

int main()
{
    int m;
    read(n); read(m);
    build(1,1,n);
    int ty,l,r,ll,rr;
    int pos;
    while(m--)
    {
        read(ty); read(l); read(r);
        if(!ty) change(1,1,n,l,r,0);
        else if(ty==1)
        {
            tot=0;
            query(1,1,n,l,r,1);
            change(1,1,n,l,r,0);
            read(ll); read(rr);
            if(!tot) continue;
            pos=find(ll,tot); //从l起,tot个1能补到哪儿 
            change(1,1,n,ll,min(pos,rr),1);
        }
        else printf("%d
",Query(1,1,n,l,r).mx0);
    }
}
原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8566174.html