- Time limit
- 3000 ms
- Memory limit
- 32768 kB
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
题解:
线段树区间合并裸题。注意要保存最长连续0,方便进行改变时直接01互换就行了。
代码:
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100005;
int Data[MAXN];
int Change[MAXN*4];
struct D{
int l1;
int l0;
int r1;
int r0;
int max1;
int max0;
int s;
}Tree[MAXN*4];
void Up(int temp){
Tree[temp].l1 = Tree[temp<<1].l1;
if(Tree[temp<<1].l1 == Tree[temp<<1].s)Tree[temp].l1 += Tree[temp<<1|1].l1;
Tree[temp].r1 = Tree[temp<<1|1].r1;
if(Tree[temp<<1|1].r1 == Tree[temp<<1|1].s)Tree[temp].r1 += Tree[temp<<1].r1;
Tree[temp].l0 = Tree[temp<<1].l0;
if(Tree[temp<<1].l0 == Tree[temp<<1].s)Tree[temp].l0 += Tree[temp<<1|1].l0;
Tree[temp].r0 = Tree[temp<<1|1].r0;
if(Tree[temp<<1|1].r0 == Tree[temp<<1|1].s)Tree[temp].r0 += Tree[temp<<1].r0;
Tree[temp].max1 = max(Tree[temp<<1].max1,Tree[temp<<1|1].max1);
Tree[temp].max1 = max(Tree[temp].max1,Tree[temp<<1].r1+Tree[temp<<1|1].l1);
Tree[temp].max0 = max(Tree[temp<<1].max0,Tree[temp<<1|1].max0);
Tree[temp].max0 = max(Tree[temp].max0,Tree[temp<<1].r0+Tree[temp<<1|1].l0);
}
void Build(int temp,int left,int right){
Tree[temp].s = right-left+1;
if(left == right){
if(Data[left]){
Tree[temp].l1 = Tree[temp].r1 = Tree[temp].max1 = 1;
Tree[temp].l0 = Tree[temp].r0 = Tree[temp].max0 = 0;
}else {
Tree[temp].l1 = Tree[temp].r1 = Tree[temp].max1 = 0;
Tree[temp].l0 = Tree[temp].r0 = Tree[temp].max0 = 1;
}
return ;
}
int mid = left + (right-left)/2;
Build(temp<<1,left,mid);
Build(temp<<1|1,mid+1,right);
Up(temp);
}
void PushDown(int temp){
if(Change[temp]){
Change[temp<<1] ^= 1;
Change[temp<<1|1] ^= 1;
swap(Tree[temp<<1].l1,Tree[temp<<1].l0);
swap(Tree[temp<<1].r1,Tree[temp<<1].r0);
swap(Tree[temp<<1].max1,Tree[temp<<1].max0);
swap(Tree[temp<<1|1].l1,Tree[temp<<1|1].l0);
swap(Tree[temp<<1|1].r1,Tree[temp<<1|1].r0);
swap(Tree[temp<<1|1].max1,Tree[temp<<1|1].max0);
Change[temp] = 0;
}
}
void Updata(int temp,int left,int right,int ql,int qr){
if(ql<=left && qr>=right){
Change[temp] ^= 1;
swap(Tree[temp].l1,Tree[temp].l0);
swap(Tree[temp].r1,Tree[temp].r0);
swap(Tree[temp].max1,Tree[temp].max0);
return ;
}
PushDown(temp);
int mid = left + (right-left)/2;
if(ql<=mid)Updata(temp<<1,left,mid,ql,qr);
if(qr>mid)Updata(temp<<1|1,mid+1,right,ql,qr);
Up(temp);
}
int query(int temp,int left,int right,int ql,int qr){
if(ql==left && qr==right)return Tree[temp].max1;
PushDown(temp);
int mid = left + (right-left)/2;
if(qr<=mid)return query(temp<<1,left,mid,ql,qr);
else if(ql>mid)return query(temp<<1|1,mid+1,right,ql,qr);
else {
int a,b,c;
a = query(temp<<1,left,mid,ql,mid);
b = query(temp<<1|1,mid+1,right,mid+1,qr);
c = min(mid-ql+1,Tree[temp<<1].r1) + min(qr-mid,Tree[temp<<1|1].l1);
return max(a,max(b,c));
}
}
int main(){
int N,M;
while(scanf("%d",&N)!=EOF){
for(int i=1 ; i<=N ; i++){
scanf("%d",&Data[i]);
}
memset(Change,0,sizeof(Change));
Build(1,1,N);
scanf("%d",&M);
int A,B,C;
while(M--){
scanf("%d %d %d",&A,&B,&C);
if(A){
Updata(1,1,N,B,C);
}else {
printf("%d
",query(1,1,N,B,C));
}
}
}
return 0;
}