hdu 3911 Black And White 一串0 1的数字 操作将一段区间[ i , j ]的每个数字进行异或操作 问区间最长0|1串

Problem Description
There are a bunch of stones on the beach; Stone color is white or black. Little Sheep has a magic brush, she can change the color of a continuous stone, black to white, white to black. Little Sheep like black very much, so she want to know the longest period of consecutive black stones in a range [i, j].
 


 

Input
  There are multiple cases, the first line of each case is an integer n(1<= n <= 10^5), followed by n integer 1 or 0(1 indicates black stone and 0 indicates white stone), then is an integer M(1<=M<=10^5) followed by M operations formatted as x i j(x = 0 or 1) , x=1 means change the color of stones in range[i,j], and x=0 means ask the longest period of consecutive black stones in range[i,j]
 


 

Output
When x=0 output a number means the longest length of black stones in range [i,j].
 


 

Sample Input
  
  
4 1 0 1 0 5 0 1 4 1 2 3 0 1 4 1 3 3 0 4 4
 


 

Sample Output
  
  
1 2 0

 

//

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=2000000;
struct Node
{
    int left,right;//左右区间
    int cover;//是否需要翻转
    int bcval,blval,brval;//black 当前最大区间,左面最大区间,右面最大区间
    int wcval,wlval,wrval;//white 当前最大区间,左面最大区间,右面最大区间
};
int n;
Node tree[maxn];
int a[maxn];//初始状态 1black  0white
int getLen(int id)
{
    return tree[id].right-tree[id].left+1;
}
void update(int id)
{
    tree[id].bcval=max(tree[id<<1].bcval,tree[(id<<1)|1].bcval);
    tree[id].bcval=max(tree[id].bcval,tree[id<<1].brval+tree[(id<<1)|1].blval);
    tree[id].blval=tree[id<<1].blval;
    if(tree[id<<1].blval==getLen(id<<1))
        tree[id].blval=tree[id<<1].blval+tree[(id<<1)|1].blval;
    tree[id].brval=tree[(id<<1)|1].brval;
    if(tree[(id<<1)|1].brval==getLen((id<<1)|1))
        tree[id].brval=tree[(id<<1)|1].brval+tree[id<<1].brval;

    tree[id].wcval=max(tree[id<<1].wcval,tree[(id<<1)|1].wcval);
    tree[id].wcval=max(tree[id].wcval,tree[id<<1].wrval+tree[(id<<1)|1].wlval);
    tree[id].wlval=tree[id<<1].wlval;
    if(tree[id<<1].wlval==getLen(id<<1))
        tree[id].wlval=tree[id<<1].wlval+tree[(id<<1)|1].wlval;
    tree[id].wrval=tree[(id<<1)|1].wrval;
    if(tree[(id<<1)|1].wrval==getLen((id<<1)|1))
        tree[id].wrval=tree[(id<<1)|1].wrval+tree[id<<1].wrval;
}
void buildtree(int id,int l,int r)
{
    tree[id].left=l,tree[id].right=r;
    tree[id].cover=0;
    if(l==r)
    {
        if(a[l])
        {
            tree[id].bcval=tree[id].blval=tree[id].brval=1;
            tree[id].wcval=tree[id].wlval=tree[id].wrval=0;
        }
        else
        {
            tree[id].bcval=tree[id].blval=tree[id].brval=0;
            tree[id].wcval=tree[id].wlval=tree[id].wrval=1;
        }
        return ;
    }
    int mid=(l+r)>>1;
    buildtree(id<<1,l,mid);
    buildtree((id<<1)|1,mid+1,r);
    update(id);
}
void push(int id)
{
    if(tree[id].cover)
    {
        tree[id].cover=!tree[id].cover;
        tree[id<<1].cover=!tree[id<<1].cover;
        tree[(id<<1)|1].cover=!tree[(id<<1)|1].cover;
        swap(tree[id].bcval,tree[id].wcval);
        swap(tree[id].blval,tree[id].wlval);
        swap(tree[id].brval,tree[id].wrval);
    }

}
void insert(int id,int l,int r)
{
    if(tree[id].left==l&&tree[id].right==r)
    {
        //important
        tree[id].cover=!tree[id].cover;
        push(id);
        return ;
    }
    push(id);
    int mid=(tree[id].left+tree[id].right)>>1;
    if(r<=mid) insert(id<<1,l,r);
    else if(l>=mid+1) insert((id<<1)|1,l,r);
    else
    {
        insert(id<<1,l,mid);
        insert((id<<1)|1,mid+1,r);
    }
    push(id<<1);
    push((id<<1)|1);
    update(id);
}
void fresh(Node &cs,Node ls,Node rs)
{
    cs.bcval=max(ls.bcval,rs.bcval);
    cs.bcval=max(cs.bcval,ls.brval+rs.blval);
    cs.blval=ls.blval;
    if(ls.blval==ls.right-ls.left+1)
        cs.blval=ls.blval+rs.blval;
    cs.brval=rs.brval;
    if(rs.brval==rs.right-rs.left+1)
        cs.brval=rs.brval+ls.brval;

    cs.wcval=max(ls.wcval,rs.wcval);
    cs.wcval=max(cs.wcval,ls.wrval+rs.wlval);
    cs.wlval=ls.wlval;
    if(ls.wlval==ls.right-ls.left+1)
        cs.wlval=ls.wlval+rs.wlval;
    cs.wrval=rs.wrval;
    if(rs.wrval==rs.right-rs.left+1)
        cs.wrval=rs.wrval+ls.wrval;
}
Node query(int id,int l,int r)
{
    if(tree[id].left==l&&tree[id].right==r)
    {
        push(id);
        return tree[id];
    }
    push(id);
    int mid=(tree[id].left+tree[id].right)>>1;
    if(r<=mid) return query(id<<1,l,r);
    else if(l>=mid+1) return query((id<<1)|1,l,r);
    else
    {
        Node cs,ls,rs;
        ls=query(id<<1,l,mid);
        rs=query((id<<1)|1,mid+1,r);
        fresh(cs,ls,rs);
        return cs;
    }
}
int main()
{
    while(scanf("%d",&n)==1)
    {
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        buildtree(1,1,n);
        int ci;scanf("%d",&ci);
        while(ci--)
        {
            int order,x,y;scanf("%d%d%d",&order,&x,&y);
            if(order==1)
            {
                insert(1,x,y);
            }
            else
            {
                Node cnt=query(1,x,y);
                printf("%d\n",cnt.bcval);
            }
        }
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值