Black And White
Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2580 Accepted Submission(s): 814
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<stdio.h> using namespace std; #define MAX 500000 typedef struct infor { int left , right , value ; }infor ; infor tree[4*MAX] ; int a[MAX+1] ; void create(int root , int left , int right) { tree[root].left = left ; tree[root].right = right ; if( right == left ) { tree[root].value = a[right] ; return ; } int mid = (left + right ) / 2 ; create(root*2 , left , mid ); create(root*2 + 1 , mid + 1 , right ); // tree[root].value = tree[root*2].value + tree[root*2 + 1].value ; } void update(int root , int left , int right , int l , int r ) { if(left == right ) { if(tree[root].value == 0 ) tree[root].value = 1 ; else tree[root].value = 0 ; return ; } int mid = (tree[root].left + tree[root].right ) / 2 ; if(l > mid ) update(root*2 + 1, mid + 1 , right , l , r ); else if(r <= mid ) update(root*2 , left , mid , l , r ); else { update(root*2 , left , mid , l , r ); update(root*2 + 1 , mid + 1 , right , l , r ); } //tree[root].value =(tree[root*2].value + tree[root*2 + 1].value ) ; } int sum ,max1; void cal(int root , int left , int right , int l , int r) { if(left == right) { if(tree[root].value == 1){ sum ++ ; return ; } else{ max1 = max1 < sum ? sum : max1 ; sum = 0 ; return ; } //return tree[root].value ; } int mid = (tree[root].left + tree[root].right ) / 2; if(l > mid ) cal(root*2 + 1 , mid + 1 , right , l , r ); else if(r <= mid ) cal(root*2 , left , mid , l , r ); else { cal(root*2 , left , mid , l , r ) ; cal(root*2 + 1 , mid + 1 , right , l , r ) ; } } int main( void ) { int n , i ; cin >> n ; for( i = 1 ; i <= n ; i ++) scanf("%d",&a[i]); create(1,1,n); int q; cin >> q ; while(q --) { int m , x , y ; while(scanf("%d %d %d",&m,&x,&y)!=EOF){ if(m==0){ sum = 0 ; max1 = 0 ; cal(1,1,n,x,y); //printf("%d\n",cal(1,1,n,x,y)); printf("%d\n",max1); } else update(1,1,n,x,y); } } return 0; }
/*还是超时算法,(*^__^*) 嘻嘻……*/#include<iostream> #include<cstdio> using namespace std; #define MAX 100000 typedef struct infor { int l , r; //l左孩子,r右孩子 int llen, rlen , len ; //llen从左边起最长黑石头序列,rlen右边起黑石头个数,最长黑石头个数 int lnum , rnum ,cnt ;//lnum最左边的石头颜色, 最右边的石头颜色 }infor ; infor t[4*MAX] ; int a[MAX + 1] ; int max(int b , int c) { return b>c?b:c ; } int min(int b , int c) { return b>c?c:b ; } void up(int rt , int lenl , int lenr) { t[rt].len = max(t[rt*2].len , t[rt*2 + 1 ].len); t[rt].llen = t[rt*2].llen ; t[rt].rlen = t[rt*2 + 1].rlen ; if(t[rt*2].rnum == 1 && t[rt*2 +1 ].lnum== 1) { t[rt].len = max(t[rt].len , t[rt*2].rlen + t[rt*2 + 1].llen); if(t[rt*2].llen >= lenl) t[rt].llen +=t[rt*2 + 1].llen ; if(t[rt*2 + 1].rlen >= lenr) t[rt].rlen +=t[rt*2].rlen ; } } void create(int rt , int l , int r) { t[rt].l = l ; t[rt].r = r ; t[rt].cnt = 0 ; if( l == r ) { if(a[l]==1) { t[rt].len = 1 ;t[rt].llen = 1;t[rt].rlen = 1;t[rt].lnum = 1 ;t[rt].rnum = 1; } else { t[rt].len = 0 ;t[rt].llen = 0;t[rt].rlen = 0;t[rt].lnum = 0 ;t[rt].rnum = 0; } return ; } int mid = (l + r) / 2 ; create(rt*2 , l , mid ); create(rt*2 + 1 , mid + 1 , r ); t[rt].lnum = t[rt*2].lnum; t[rt].rnum = t[rt*2 + 1 ].rnum ; up(rt , mid - l + 1 , r - mid ); } void update(int rt , int l , int r , int x , int y) { if(t[rt].l == t[rt].r ) { if(t[rt].lnum ==1) { t[rt].lnum = 0 ;t[rt].rnum = 0 ;t[rt].len = 0;t[rt].llen = 0 ;t[rt].rlen = 0 ; } else { t[rt].lnum = 1 ;t[rt].rnum = 1 ;t[rt].len = 1;t[rt].rlen = 1;t[rt].llen = 1 ; } return ; } int mid = (t[rt].l + t[rt].r) / 2 ; if(t[rt].cnt) { up(rt , mid - l + 1 , r - mid ); t[rt].cnt = 0 ; } if(x>mid) update(rt*2 + 1 , mid + 1 , r , x , y); else if(y<= mid) update(rt*2 , l , mid , x , y ); else { update(rt*2 , l , mid , x , y ); update(rt*2 + 1 , mid + 1 , r , x , y ); } t[rt].lnum = t[rt*2].lnum; t[rt].rnum = t[rt*2 + 1 ].rnum ; up(rt , mid - l + 1 , r - mid ); } int cal(int rt , int l , int r , int x , int y) { if(x<=l && y>=r) return t[rt].len ; int mid = (t[rt].l + t[rt].r ) / 2 ; if(x > mid ) return cal(rt*2 + 1 , mid + 1 , r , x , y ); else if(y<=mid) return cal(rt*2 , l , mid , x , y ); int ret = max(cal(rt*2 + 1 , mid + 1 , r , x , y),cal(rt*2 , l , mid , x , y )); if(t[rt*2 + 1].lnum== 1 && t[rt*2].rnum == 1) return ret=max(ret , min(y, mid + t[rt*2 + 1 ].llen ) - max(x , mid - t[rt*2].rlen + 1) + 1); return ret ; } int main(void ) { int n , i ; cin>>n ; for( i = 1; i <= n ; i ++) scanf("%d",&a[i]); create( 1 , 1, n ); int m ; scanf("%d",&m); while(m--) { int val , x , y; scanf("%d %d %d",&val , &x , &y); if(val==1) update( 1 , 1 , n, x, y); else printf("%d\n",cal(1 , 1, n, x, y)); } return 0; }
/注:转载/#include<stdio.h> struct haha { int left; int right; int l_b;//、 lb表示区间从左边开始连续的1的个数 如当前区间为1-10 那么这个就代表包含1的最长1串 int r_b;//、 rb表示区间从右边开始连续的1的个数 如当前区间为1-10 那么这个就代表包含10的最长1串 int l_w;//、 lw表示区间从左边开始连续的0的个数 int r_w;//、 rw表示区间从右边开始连续的0的个数 int maxb; int maxw; int cnt; /*cnt表示区间被访问的次数,这里利用它实现lazy思xiang 这里简述一下lazy思想:每次访问的时候不用都更新到最低层的元线段,每次只访问到恰好的区间, 在这里设一个标志,表示这次更新只访问到了该区间!那么当再次访问该区间的时候就需要将该标志往其子区间传递*/ }tree[100000*4]; int max(int a,int b) { if(a>b) return a; else return b; } int min(int a,int b) { if(a<b) return a; else return b; } void update(int nd) { int left_len,right_len; tree[nd].maxb=max(max(tree[nd*2].maxb,tree[nd*2+1].maxb),tree[nd*2].r_b+tree[nd*2+1].l_b); tree[nd].maxw=max(max(tree[nd*2].maxw,tree[nd*2+1].maxw),tree[nd*2].r_w+tree[nd*2+1].l_w); left_len=tree[nd*2].right-tree[nd*2].left+1; right_len=tree[nd*2+1].right-tree[nd*2+1].left+1; tree[nd].l_b=tree[nd*2].l_b; if(tree[nd*2].l_b==left_len) tree[nd].l_b+=tree[nd*2+1].l_b; tree[nd].l_w=tree[nd*2].l_w; if(tree[nd*2].l_w==left_len) tree[nd].l_w+=tree[nd*2+1].l_w; tree[nd].r_b=tree[nd*2+1].r_b; if(tree[nd*2+1].r_b==right_len) tree[nd].r_b+=tree[nd*2].r_b; tree[nd].r_w=tree[nd*2+1].r_w; if(tree[nd*2+1].r_w==right_len) tree[nd].r_w+=tree[nd*2].r_w; } void build(int nd,int left,int right) { int mid,num; tree[nd].left=left;tree[nd].right=right; tree[nd].cnt=0; if(left==right) { scanf("%d",&num); if(num) {tree[nd].maxb=tree[nd].l_b=tree[nd].r_b=1; tree[nd].maxw=tree[nd].l_w=tree[nd].r_w=0; } else {tree[nd].maxw=tree[nd].l_w=tree[nd].r_w=1; tree[nd].maxb=tree[nd].l_b=tree[nd].r_b=0; } return; } mid=(left+right)/2; build(nd*2,left,mid); build(nd*2+1,mid+1,right);//是mid+1 RUNTIEM ERROR 了好几次 update(nd); } void change(int nd) { int temp; temp=tree[nd].l_b;tree[nd].l_b=tree[nd].l_w;tree[nd].l_w=temp; temp=tree[nd].maxb;tree[nd].maxb=tree[nd].maxw;tree[nd].maxw=temp; temp=tree[nd].r_b;tree[nd].r_b=tree[nd].r_w;tree[nd].r_w=temp; tree[nd].cnt=!tree[nd].cnt; } void update2(int nd,int left,int right) { int mid; if(tree[nd].left==left&&tree[nd].right==right) { change(nd); return ; } if(tree[nd].cnt) {change(nd*2);change(nd*2+1);tree[nd].cnt=0;} mid=(tree[nd].left+tree[nd].right)/2; if(right<=mid) update2(nd*2,left,right); else if(left>mid) update2(nd*2+1,left,right); else {update2(nd*2,left,mid);update2(nd*2+1,mid+1,right);}//是mid+1 RUNTIEM ERROR 了好几次 update(nd); } int query(int nd,int left,int right) { int mid,lr,rr; if(tree[nd].left==left&&tree[nd].right==right) return tree[nd].maxb; if(tree[nd].cnt) {change(nd*2);change(nd*2+1);tree[nd].cnt=0;} mid=(tree[nd].right+tree[nd].left)/2; if(right<=mid) return query(nd*2,left,right); else if(left>mid)return query(nd*2+1,left,right); else { lr=query(nd*2,left,mid); rr=query(nd*2+1,mid+1,right); return max(max(min(tree[nd*2].r_b,lr)+min(tree[nd*2+1].l_b,rr),lr),rr);//这句话真心不懂啊! // return max(max(tree[nd*2].r_b+tree[nd*2+1].l_b,lr),rr); } } int main() { int n,i,opr,m,left,right; while(scanf("%d",&n)!=EOF) { build(1,1,n); scanf("%d",&m); for(i=1;i<=m;i++) { scanf("%d %d %d",&opr,&left,&right); if(opr) update2(1,left,right); else printf("%d\n",query(1,left,right)); } } return 0; }