- 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\n",query(1,1,N,B,C)); } } } return 0; }