1. 程式人生 > >HDU - 3911 Black And White 線段樹 區間合併

HDU - 3911 Black And White 線段樹 區間合併

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>
using namespace std;
const int N=1e5+10;
struct node
{
    int l,r,len;
    int l0,r0,max0;
    int l1,r1,max1;
    int laz;
}tree[N<<2];
int n,q,x;
void pushup(int cur)
{
    tree[cur].l0=tree[cur<<1].l0;
    if(tree[cur<<1].l0==tree[cur<<1].len)
        tree[cur].l0+=tree[cur<<1|1].l0;
    tree[cur].r0=tree[cur<<1|1].r0;
    if(tree[cur<<1|1].r0==tree[cur<<1|1].len)
        tree[cur].r0+=tree[cur<<1].r0;
    tree[cur].max0=max(tree[cur<<1].max0,tree[cur<<1|1].max0);
    tree[cur].max0=max(tree[cur].max0,tree[cur<<1].r0+tree[cur<<1|1].l0);

    tree[cur].l1=tree[cur<<1].l1;
    if(tree[cur<<1].l1==tree[cur<<1].len)
        tree[cur].l1+=tree[cur<<1|1].l1;
    tree[cur].r1=tree[cur<<1|1].r1;
    if(tree[cur<<1|1].r1==tree[cur<<1|1].len)
        tree[cur].r1+=tree[cur<<1].r1;
    tree[cur].max1=max(tree[cur<<1].max1,tree[cur<<1|1].max1);
    tree[cur].max1=max(tree[cur].max1,tree[cur<<1].r1+tree[cur<<1|1].l1);
}
void build(int l,int r,int cur)
{
    tree[cur].laz=0;
    tree[cur].l=l;
    tree[cur].r=r;
    tree[cur].len=r-l+1;
    if(l==r)
    {
        scanf("%d",&x);
        tree[cur].l1=tree[cur].r1=tree[cur].max1=(x==1);
        tree[cur].l0=tree[cur].r0=tree[cur].max0=(x==0);
        return;
    }
    int mid=(r+l)>>1;
    build(l,mid,cur<<1);
    build(mid+1,r,cur<<1|1);
    pushup(cur);
}
void change(int cur)
{
    swap(tree[cur].l0,tree[cur].l1);
    swap(tree[cur].r0,tree[cur].r1);
    swap(tree[cur].max0,tree[cur].max1);
}
void pushdown(int cur)
{
    if(tree[cur].laz)
    {
        tree[cur<<1].laz^=1;
        tree[cur<<1|1].laz^=1;
        change(cur<<1);
        change(cur<<1|1);
        tree[cur].laz=0;
    }
}

void update(int pl,int pr,int cur)
{
    if(pl<=tree[cur].l&&tree[cur].r<=pr)
    {
        tree[cur].laz^=1;
        change(cur);
        return;
    }
    pushdown(cur);
    if(pl<=tree[cur<<1].r) update(pl,pr,cur<<1);
    if(pr>=tree[cur<<1|1].l) update(pl,pr,cur<<1|1);
    pushup(cur);
}
int query(int pl,int pr,int cur)
{
    if(pl<=tree[cur].l&&tree[cur].r<=pr)
    {
        return tree[cur].max1;
    }
    pushdown(cur);
    if(pr<=tree[cur<<1].r) return query(pl,pr,cur<<1);
    else if(pl>=tree[cur<<1|1].l) return query(pl,pr,cur<<1|1);
    else
    {
        int res=min(pr,tree[cur<<1|1].l1+tree[cur<<1|1].l-1)-max(pl,tree[cur<<1].r-tree[cur<<1].r1+1)+1;
        res=max(res,query(pl,pr,cur<<1));
        res=max(res,query(pl,pr,cur<<1|1));
        return res;
    }
}
int main()
{
    int op,l,r;
    while(~scanf("%d",&n))
    {
        build(1,n,1);
        scanf("%d",&q);
        while(q--)
        {
            scanf("%d%d%d",&op,&l,&r);
            if(op==0)
            {
                printf("%d\n",query(l,r,1));
            }
            else
            {
                update(l,r,1);
            }
        }
    }
    return 0;
}