HDU-3397-Sequence operation(区间染色 连续为1的序列)

题目
lxhgww得到一个包含n个字符的序列,这些字符都是“0”或“1”。
我们有五个操作:
改变操作:
将[a, b]中的所有字符改为’0’
将[a, b]中的所有字符改为’1’
把所有的0都变成1把所有的1都变成0
输出操作:
输出[a, b]中’1’的个数
输出[a, b]中最长的连续“1”字符串的长度。

输入

第一行中的T(T<=10)是箱号。
每一种情况在第一行有两个整数:n和m (1 <= n, m <= 100000)。
下一行包含n个字符,“0”或“1”由空格分隔。
m行为操作:
op a b: 0 <= op <= 4, 0 <= a <= b < n。

输出

对于每个输出操作,输出结果。

用 ls[ ] ,rs[ ] 前后缀连续为1的数列长度。
fs[pos]=max( fs[pos<<1],fs[pos<<1|1]).
fs[pos]=max( fs[pos], min(mid-cl+1,rs[pos<<1])+min(cr-mid,ls[pos<<1|1]).

区间染色
pushup中tag也要上推???感觉是吧。不知道不知道。 一会儿写染色后来补

这个和区间染色是肯定不同的啊。因为其中 异或 的时候相当于对 tag[pos]!=-1的左右区间 分别染色。故此时需要判断tag[pos]!=-1? 。。若等于-1的话。区间还要继续往下划分。tag 一定要上推。而且求 sum fs …等等与 tag的值有关。

#include <algorithm>
#include <cstdio>
using namespace std;
const int N=100005*4;
int sum[N],tag[N],fs[N],ls[N],rs[N],cur[N];
void pushup(int ln,int rn,int pos)
{
    if(tag[pos<<1]==tag[pos<<1|1])
        tag[pos]=tag[pos<<1];
    else
        tag[pos]=-1;
    if(tag[pos]!=-1)
        sum[pos]=fs[pos]=ls[pos]=rs[pos]=(tag[pos]?(ln+rn):0);
    else
    {
        sum[pos]=sum[pos<<1]+sum[pos<<1|1];
        fs[pos]=max(fs[pos<<1],fs[pos<<1|1]);
        fs[pos]=max(fs[pos],rs[pos<<1]+ls[pos<<1|1]);
        ls[pos]=ls[pos<<1];
        rs[pos]=rs[pos<<1|1];
        if(ls[pos<<1]==ln)
            ls[pos]=ln+ls[pos<<1|1];
        if(rs[pos<<1|1]==rn)
            rs[pos]=rs[pos<<1]+rn;
    }
}
void build(int l,int r,int pos)
{
    if(l==r)
    {
        tag[pos]=cur[l];
        sum[pos]=fs[pos]=ls[pos]=rs[pos]=cur[l];
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,pos<<1);
    build(mid+1,r,pos<<1|1);
    pushup(mid-l+1,r-mid,pos);
}
void pushdown(int ln,int rn,int pos)
{
    if(tag[pos]==-1)
        return;
    tag[pos<<1]=tag[pos<<1|1]=tag[pos];
    sum[pos<<1]=fs[pos<<1]=ls[pos<<1]=rs[pos<<1]=(tag[pos]?ln:0);
    sum[pos<<1|1]=fs[pos<<1|1]=ls[pos<<1|1]=rs[pos<<1|1]=(tag[pos]?rn:0);
    tag[pos]=-1;
}
void chanspan(int cl,int cr,int val,int l,int r,int pos)
{
    if(cl<=l&&r<=cr)
    {
        tag[pos]=val;
        sum[pos]=fs[pos]=ls[pos]=rs[pos]=(tag[pos]?(r-l+1):0);
        return;
    }
    int mid=(l+r)>>1;
    pushdown(mid-l+1,r-mid,pos);
    if(cl<=mid)
        chanspan(cl,cr,val,l,mid,pos<<1);
    if(cr>mid)
        chanspan(cl,cr,val,mid+1,r,pos<<1|1);
    pushup(mid-l+1,r-mid,pos);
}
void chanpoint(int cl,int cr,int l,int r,int pos)
{
    if(cl<=l&&r<=cr&&tag[pos]!=-1)
    {
        tag[pos]^=1;
        sum[pos]=fs[pos]=ls[pos]=rs[pos]=(tag[pos]?(r-l+1):0);
        return;
    }
    int mid=(l+r)>>1;
    pushdown(mid-l+1,r-mid,pos);
    if(cl<=mid)
        chanpoint(cl,cr,l,mid,pos<<1);
    if(cr>mid)
        chanpoint(cl,cr,mid+1,r,pos<<1|1);
    pushup(mid-l+1,r-mid,pos);
}
int series_1(int cl,int cr,int l,int r,int pos)
{
    if(cl<=l&&r<=cr)
        return fs[pos];
    int mid=(l+r)>>1;
    pushdown(mid-l+1,r-mid,pos);
    int ans=-1;
    if(cl<=mid)
        ans=max(ans,series_1(cl,cr,l,mid,pos<<1));
    if(cr>mid)
        ans=max(ans,series_1(cl,cr,mid+1,r,pos<<1|1));
    ans=max(ans,min(mid-cl+1,rs[pos<<1])+min(cr-mid,ls[pos<<1|1]));
    return ans;
}
int num_1(int cl,int cr,int l,int r,int pos)
{
    if(cl<=l&&r<=cr)
        return sum[pos];
    int mid=(l+r)>>1;
    pushdown(mid-l+1,r-mid,pos);
    int ans=0;
    if(cl<=mid)
        ans+=num_1(cl,cr,l,mid,pos<<1);
    if(cr>mid)
        ans+=num_1(cl,cr,mid+1,r,pos<<1|1);
    return ans;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%d",&cur[i]);
        build(1,n,1);
        while(m--)
        {
            int k,cl,cr;
            scanf("%d%d%d",&k,&cl,&cr);
            cl++,cr++;
            if(k==0)
                chanspan(cl,cr,0,1,n,1);
            if(k==1)
                chanspan(cl,cr,1,1,n,1);
            if(k==2)
                chanpoint(cl,cr,1,n,1);
            if(k==3)
                printf("%d\n",num_1(cl,cr,1,n,1));
            if(k==4)
                printf("%d\n",series_1(cl,cr,1,n,1));
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_42576687/article/details/87890545