HDU 3911 线段树区间合并

Black And White

Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2964    Accepted Submission(s): 936

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
与poj hotel类似,做法也基本一模一样。
代码:
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
using namespace std;
const int maxn=111111;
#define L(x) 2*x
#define R(x) 2*x+1
struct node
{
        int l,r,lsum0,rsum0,vsum0,lsum1,rsum1,vsum1,rox;
        int mid(){return (l+r)>>1;}
        int len(){return r-l+1;}
}tree[5*maxn];
void pushup(int p)
{
      tree[p].lsum0=tree[L(p)].lsum0;
      tree[p].rsum0=tree[R(p)].rsum0;
      if(tree[L(p)].lsum0==tree[L(p)].len())tree[p].lsum0+=tree[R(p)].lsum0;
      if(tree[R(p)].rsum0==tree[R(p)].len())tree[p].rsum0+=tree[L(p)].rsum0;
      tree[p].vsum0=max(max(tree[L(p)].vsum0,tree[R(p)].vsum0),tree[L(p)].rsum0+tree[R(p)].lsum0);

      tree[p].lsum1=tree[L(p)].lsum1;
      tree[p].rsum1=tree[R(p)].rsum1;
      if(tree[L(p)].lsum1==tree[L(p)].len())tree[p].lsum1+=tree[R(p)].lsum1;
      if(tree[R(p)].rsum1==tree[R(p)].len())tree[p].rsum1+=tree[L(p)].rsum1;
      tree[p].vsum1=max(max(tree[L(p)].vsum1,tree[R(p)].vsum1),tree[L(p)].rsum1+tree[R(p)].lsum1);
}
void pushdown(int p)
{
        if(tree[p].rox)
        {
                tree[L(p)].rox^=1;
                tree[R(p)].rox^=1;
                swap(tree[L(p)].lsum0,tree[L(p)].lsum1);
                swap(tree[L(p)].rsum0,tree[L(p)].rsum1);
                swap(tree[L(p)].vsum0,tree[L(p)].vsum1);

                swap(tree[R(p)].lsum0,tree[R(p)].lsum1);
                swap(tree[R(p)].rsum0,tree[R(p)].rsum1);
                swap(tree[R(p)].vsum0,tree[R(p)].vsum1);

                tree[p].rox^=1;
        }
}
void build(int p,int l,int r)
{
        tree[p].l=l;
        tree[p].r=r;
        tree[p].rox=0;
        if(l==r)
        {
                int c;
                scanf("%d",&c);
                tree[p].lsum1=tree[p].rsum1=tree[p].vsum1=c;
                tree[p].lsum0=tree[p].rsum0=tree[p].vsum0=c^1;
                return;
        }
        int m=tree[p].mid();
        build(L(p),l,m);
        build(R(p),m+1,r);
        pushup(p);
}
void update(int p,int l,int r)
{
        if(tree[p].l>=l&&tree[p].r<=r)
        {
                tree[p].rox^=1;
                swap(tree[p].lsum0,tree[p].lsum1);
                swap(tree[p].rsum0,tree[p].rsum1);
                swap(tree[p].vsum0,tree[p].vsum1);
                return;
        }
        pushdown(p);
        int m=tree[p].mid();
        if(l<=m)update(L(p),l,r);
        if(r>m)update(R(p),l,r);
        pushup(p);
}
int query(int p,int l,int r)
{
        if(tree[p].l>=l&&tree[p].r<=r)return tree[p].vsum1;
        int ret;
        pushdown(p);
        int m=tree[p].mid();
        if(m>=r)ret=query(L(p),l,r);
        else if(m<l)ret=query(R(p),l,r);
        else
        {
                ret=max(query(L(p),l,r),query(R(p),l,r));
                int ret1=min(m-l+1,tree[L(p)].rsum1);
                int ret2=min(r-m,tree[R(p)].lsum1);
                ret=max(ret,ret1+ret2);
        }
        return ret;
}
int main()
{
        int n,m,i,j,k;
        while(~scanf("%d",&n))
        {
                build(1,1,n);
                scanf("%d",&m);
                while(m--)
                {
                        scanf("%d%d%d",&i,&j,&k);
                        if(i==1)update(1,j,k);
                        else printf("%d\n",query(1,j,k));
                }
                //cout<<tree[1].vsum1<<endl;
        }
        return 0;
}

 

posted @ 2013-09-26 20:53  线性无关  阅读(132)  评论(0)    收藏  举报