题目描述
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].
输入
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]
输出
When x=0 output a number means the longest length of black stones in range [i,j].
样例输入
4 1 0 1 0 5 0 1 4 1 2 3 0 1 4 1 3 3 0 4 4
样例输出
1 2 0
虽然说这是一道简单线段树的问题,但是好复杂啊,比赛的时候碰到这题,没有扎实的能力,我想是出不了的
线段树,只是在修改更新节点的时候,不想以往那样一句搞定,而是更加复杂,更加有难度了
#include<map> #include<set> #include<queue> #include<cmath> #include<vector> #include<cstdio> #include<string> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define inf 0x0f0f0f0f using namespace std; const int maxn=100000+10; int a[maxn]; struct node { int left,right,lmax,rmax,lcor,rcor,mark,maxb,maxw; }tree[maxn*4]; void build(int c,int x,int y) { tree[c].lcor=0; tree[c].left=x; tree[c].lmax=0; tree[c].maxb=0; tree[c].maxw=0; tree[c].rcor=0; tree[c].right=y; tree[c].rmax=0; tree[c].mark=0; if (x==y) return; int mid=x+(y-x)/2; build(c*2,x,mid); build(c*2+1,mid+1,y); } void change(int c) { tree[c].lcor=tree[c].lcor^1; tree[c].rcor=tree[c].rcor^1; swap(tree[c].maxb,tree[c].maxw); tree[c].mark=tree[c].mark^1; } void update_t(int c) { tree[c].lcor=tree[c*2].lcor; tree[c].rcor=tree[c*2+1].rcor; tree[c].lmax=tree[c*2].lmax; if (tree[c*2].lmax==tree[c*2].right-tree[c*2].left+1 && tree[c*2+1].lcor==tree[c*2].rcor) tree[c].lmax=tree[c*2].lmax+tree[c*2+1].lmax; tree[c].rmax=tree[c*2+1].rmax; if (tree[c*2+1].rmax==tree[c*2+1].right-tree[c*2+1].left+1 && tree[c*2+1].lcor==tree[c*2].rcor) tree[c].rmax=tree[c*2+1].rmax+tree[c*2].rmax; tree[c].maxb=max(tree[c*2].maxb,tree[c*2+1].maxb); if (tree[c*2].rcor==1 && tree[c*2+1].lcor==1) tree[c].maxb=max(tree[c].maxb,tree[c*2].rmax+tree[c*2+1].lmax); tree[c].maxw=max(tree[c*2].maxw,tree[c*2+1].maxw); if (tree[c*2].rcor==0 && tree[c*2+1].lcor==0) tree[c].maxw=max(tree[c].maxw,tree[c*2].rmax+tree[c*2+1].lmax); } void update_one(int c) { if (tree[c].left==tree[c].right) { tree[c].mark=0; tree[c].lmax=tree[c].rmax=1; if (a[tree[c].left]==1) { tree[c].maxb=1; tree[c].maxw=0; tree[c].lcor=tree[c].rcor=1; } else { tree[c].maxb=0; tree[c].maxw=1; tree[c].lcor=tree[c].rcor=0; } return; } update_one(c*2); update_one(c*2+1); update_t(c); } void update(int c,int x,int y) { if (tree[c].left==x && tree[c].right==y) { change(c); return; } if (tree[c].mark) { change(c*2); change(c*2+1); tree[c].mark=0; } int mid=tree[c].left+(tree[c].right-tree[c].left)/2; if (y<=mid) update(c*2,x,y); else if(x>mid) update(c*2+1,x,y); else { update(c*2,x,mid); update(c*2+1,mid+1,y); } update_t(c); } int reseach_tree(int c,int x,int y) { if (tree[c].left==x && tree[c].right==y) return tree[c].maxb; if (tree[c].mark) { change(c*2); change(c*2+1); tree[c].mark=0; } int mid=tree[c].left+(tree[c].right-tree[c].left)/2; int ans1=0,ans2=0,ans3=0,ans4=0,ans5=0; if (y<=mid) ans1=reseach_tree(c*2,x,y); else if (x>mid) ans2=reseach_tree(c*2+1,x,y); else { ans3=reseach_tree(c*2,x,mid); ans4=reseach_tree(c*2+1,mid+1,y); if (tree[c*2].rcor==tree[c*2+1].lcor && tree[c*2].rcor==1) ans5=min(mid-x+1,tree[c*2].rmax)+min(y-mid,tree[c*2+1].lmax); } update_t(c); return max(ans1,max(max(ans2,ans3),max(ans4,ans5))); } int main() { int n,m,x,y,c; while(scanf("%d",&n)!=EOF) { for (int i=1;i<=n;i++) scanf("%d",&a[i]); scanf("%d",&m); build(1,1,n); update_one(1); while(m--) { scanf("%d%d%d",&c,&x,&y); if (c==1) update(1,x,y); else printf("%d ",reseach_tree(1,x,y)); } } return 0; }
作者 chensunrise