题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3911
Black And White
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<string.h>
using namespace std;
#define Max(a,b) (((a)>(b))?(a):(b))
#define Min(a,b) (((a)<(b))?(a):(b))
#define N 100100
struct node
{
int l,r,cover,tag;
int b,w;//最大连续的黑色和白色的个数
int lval,rval;//与左右端点相同的连续颜色的个数
int lc,rc;//左右端点的颜色
int calmid()
{
return (l+r)>>1;
}
}b[4*N];
int a[N];
void update(int i)
{
b[i].b = Max( b[i+i].b, b[i+i+1].b );
b[i].w = Max( b[i+i].w, b[i+i+1].w );
b[i].lval = b[i+i].lval;
b[i].rval = b[i+i+1].rval;
if( b[i+i].rc == b[i+i+1].lc )
if( b[i+i].rc == 1 )
b[i].b = Max( b[i].b, b[i+i].rval + b[i+i+1].lval );
else
b[i].w = Max( b[i].w, b[i+i].rval + b[i+i+1].lval);
if( b[i+i].cover != -1 && b[i+i+1].lc == b[i+i].cover )
b[i].lval = b[i].lval + b[i+i+1].lval;
if( b[i+i+1].cover != -1 && b[i+i].rc == b[i+i+1].cover )
b[i].rval = b[i].rval + b[i+i].rval;
b[i].lc = b[i+i].lc;
b[i].rc = b[i+i+1].rc;
if( b[i+i].cover == b[i+i+1].cover)
b[i].cover = b[i+i].cover;
else
b[i].cover = -1;
}
void build(int i, int l, int r)
{
b[i].l = l;
b[i].r = r;
b[i].cover = -1;
b[i].tag = 0;//开始没有延迟
b[i].lc = b[i].rc = -1;
b[i].b = b[i].w = 0;
b[i].lval = b[i].rval = 0;
if( l==r )
{
b[i].lc = b[i].rc = a[l];
if(a[l] == 1)
{
b[i].b = 1;
b[i].cover = 1;
}
else
{
b[i].w = 1;
b[i].cover = 0;
}
b[i].lval = b[i].rval = 1;
return ;
}
int mid = (l+r)>>1;
build(i+i, l, mid);
build(i+i+1, mid+1, r);
update(i);
}
void samp(int i)
{
int t;
t = b[i].b, b[i].b = b[i].w, b[i].w = t;
b[i].lc = b[i].lc^1;
b[i].rc = b[i].rc^1;
if( b[i].cover!=-1 )
b[i].cover = b[i].cover^1;
}
void update(int i, int l, int r)
{
if( l<=b[i].l && b[i].r<=r )
{
samp(i);
b[i].tag = b[i].tag^1; //在这没有向下更新
return ;
}
if( b[i].tag )//如果延迟了,并且递归到这一层,要向下更新
{
samp(i+i);
samp(i+i+1);
b[i+i].tag = b[i+i].tag^1;
b[i+i+1].tag = b[i+i+1].tag^1;
b[i].tag = 0;
}
int mid = b[i].calmid();
if( l<=mid )
update(i+i,l,r);
if( r>mid )
update(i+i+1,l,r);
update(i);
}
int query(int i, int l, int r)
{
int ans;
if( l==b[i].l && b[i].r==r )
return b[i].b;
if( b[i].tag )
{
samp(i+i+1);
samp(i+i);
b[i+i].tag = b[i+i].tag^1;
b[i+i+1].tag = b[i+i+1].tag^1;
b[i].tag = 0;
}
int mid = b[i].calmid();
if( r<=mid )
ans = query(i+i, l, r);
else if( l>mid )
ans = query(i+i+1,l,r);
else
{
int lb = query(i+i, l, mid);
int rb = query(i+i+1, mid+1, r);
ans = Max(lb,rb);
if( b[i+i].rc == 1 && b[i+i+1].lc ==1)
ans = Max(ans, Min(mid-l+1,b[i+i].rval)+Min(r-mid,b[i+i+1].lval));
if( ans>r-l+1)
ans = r-l+1;
}
update(i);
return ans;
}
int main()
{
int n,m,i,tag,l,r;
while(scanf("%d", &n)!=EOF)
{
for(i=1; i<=n; i++)
scanf("%d", &a[i]);
build(1,1,n);
scanf("%d", &m);
for(i=0; i<m; i++)
{
scanf("%d%d%d", &tag, &l, &r);
if( tag==0 )
{
int ans = query(1,l,r);
printf("%d\n", ans);
}
else
update(1,l,r);
}
}
return 0;
}