Black And White
Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3082 Accepted Submission(s): 960
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
Source
额,记得当年多校的时候宣姐在这题上搞了好久好久,显然我现在也步了他的后尘……orz
其他没什么说的,就是如果连续两次同一个区间反转的时候需要把lazy调回来,然后我lazy一直都用来标识是否有修改过。。所以当同一个区间反转两次的时候就没有把lazy调回来,之后往下传数据的时候就会当作需要修改而把整段区间反转了……orz……
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
typedef struct
{
int l,r,lb,rb,lw,rw,b,w,lazy;
}Tree;
Tree tree[500005];
void Push_up(int t)
{
int l=(tree[2*t+1].rb==0?0:1);
int r=(tree[2*t+2].lb==0?0:1);
if (l!=r)
{
tree[t].b=max(tree[2*t+1].b,tree[2*t+2].b);
tree[t].w=max(tree[2*t+1].w,tree[2*t+2].w);
tree[t].lb=tree[2*t+1].lb;
tree[t].lw=tree[2*t+1].lw;
tree[t].rb=tree[2*t+2].rb;
tree[t].rw=tree[2*t+2].rw;
}
else if (l==0)
{
tree[t].b=max(tree[2*t+1].b,tree[2*t+2].b);
tree[t].lb=tree[2*t+1].lb;
tree[t].rb=tree[2*t+2].rb;
if (tree[2*t+1].w==tree[2*t+1].r-tree[2*t+1].l+1) tree[t].lw=tree[2*t+1].lw+tree[2*t+2].lw;
else tree[t].lw=tree[2*t+1].lw;
if (tree[2*t+2].w==tree[2*t+2].r-tree[2*t+2].l+1) tree[t].rw=tree[2*t+1].rw+tree[2*t+2].rw;
else tree[t].rw=tree[2*t+2].rw;
tree[t].w=max(max(tree[2*t+1].w,tree[2*t+2].w),tree[2*t+1].rw+tree[2*t+2].lw);
}
else
{
tree[t].w=max(tree[2*t+1].w,tree[2*t+2].w);
tree[t].lw=tree[2*t+1].lw;
tree[t].rw=tree[2*t+2].rw;
if (tree[2*t+1].b==tree[2*t+1].r-tree[2*t+1].l+1) tree[t].lb=tree[2*t+1].lb+tree[2*t+2].lb;
else tree[t].lb=tree[2*t+1].lb;
if (tree[2*t+2].b==tree[2*t+2].r-tree[2*t+2].l+1) tree[t].rb=tree[2*t+1].rb+tree[2*t+2].rb;
else tree[t].rb=tree[2*t+2].rb;
tree[t].b=max(max(tree[2*t+1].b,tree[2*t+2].b),tree[2*t+1].rb+tree[2*t+2].lb);
}
}
void Push_down(int t)
{
tree[2*t+1].lazy=!tree[2*t+1].lazy;
tree[2*t+2].lazy=!tree[2*t+2].lazy;
tree[t].lazy=0;
swap(tree[2*t+1].b,tree[2*t+1].w);
swap(tree[2*t+1].lb,tree[2*t+1].lw);
swap(tree[2*t+1].rb,tree[2*t+1].rw);
swap(tree[2*t+2].b,tree[2*t+2].w);
swap(tree[2*t+2].lb,tree[2*t+2].lw);
swap(tree[2*t+2].rb,tree[2*t+2].rw);
}
void Build(int t,int l,int r)
{
tree[t].l=l;
tree[t].r=r;
tree[t].lazy=0;
if (l==r)
{
int x;
scanf("%d",&x);
if (x==0)
{
tree[t].w=tree[t].lw=tree[t].rw=1;
tree[t].b=tree[t].lb=tree[t].rb=0;
}
else
{
tree[t].w=tree[t].lw=tree[t].rw=0;
tree[t].b=tree[t].lb=tree[t].rb=1;
}
return;
}
int mid=(l+r)>>1;
Build(2*t+1,l,mid);
Build(2*t+2,mid+1,r);
Push_up(t);
// printf("%d %d %d %d %d %d %d %d\n",l,r,tree[t].w,tree[t].lw,tree[t].rw,tree[t].b,tree[t].lb,tree[t].rb);
}
void Update(int t,int l,int r)
{
if (tree[t].l==l && tree[t].r==r)
{
swap(tree[t].b,tree[t].w);
swap(tree[t].lb,tree[t].lw);
swap(tree[t].rb,tree[t].rw);
tree[t].lazy=!tree[t].lazy;
return;
}
if (tree[t].lazy==1)
{
Push_down(t);
}
int mid=(tree[t].l+tree[t].r)>>1;
if (l<=mid) Update(2*t+1,l,min(mid,r));
if (r>mid) Update(2*t+2,max(l,mid+1),r);
Push_up(t);
}
int Query(int t,int l,int r)
{
if (tree[t].l==l && tree[t].r==r)
{
return tree[t].b;
}
if (tree[t].lazy==1)
{
Push_down(t);
}
int mid=(tree[t].l+tree[t].r)>>1;
int ret=0;
if (l<=mid) ret=max(ret,Query(2*t+1,l,min(r,mid)));
if (r>mid) ret=max(ret,Query(2*t+2,max(l,mid+1),r));
if (l<=mid && mid<r) ret=max(ret,min(tree[2*t+1].rb,mid-l+1)+min(tree[2*t+2].lb,r-mid));
return ret;
}
int main()
{
int i,j,n,T,x,y,z;
while(scanf("%d",&n)!=EOF)
{
Build(0,0,n-1);
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&x,&y,&z);
if (x==0)
{
printf("%d\n",Query(0,y-1,z-1));
}
else
{
Update(0,y-1,z-1);
}
}
}
return 0;
}