Sequence operation

来源:互联网 发布:自拍的淘宝图片 编辑:程序博客网 时间:2024/06/08 00:50

Problem Description

lxhgww got a sequence contains n characters which are all '0's or '1's.
We have five operations here:
Change operations:
0 a b change all characters into '0's in [a , b]
1 a b change all characters into '1's in [a , b]
2 a b change all '0's into '1's and change all '1's into '0's in [a, b]
Output operations:
3 a b output the number of '1's in [a, b]
4 a b output the length of the longest continuous '1' string in [a , b]

Input

T(T<=10) in the first line is the case number.
Each case has two integers in the first line: n and m (1 <= n , m <= 100000).
The next line contains n characters, '0' or '1' separated by spaces.
Then m lines are the operations:
op a b: 0 <= op <= 4 , 0 <= a <= b < n.

Output

For each output operation , output the result.

Sample Input

110 100 0 0 1 1 0 1 0 1 11 0 23 0 52 2 24 0 40 3 62 3 74 2 81 0 50 5 63 3 9

Sample Output

5265
/*
        题意:首先给出一组数据:由0和1组成;
                     然后有5种操作:
                         0 a b表示把[a,b]区间的数全部变成0;
                         1 a b 表示把[a,b]区间的数全部变成1;
                         2 a b表示把[a,b]区间的0变成1、1变成0,也就是进行异或操作;
                         3 a b就是问你[a,b]区间总共有多少个1;
                         4 a b就是问你[a,b]区间最长的连续的1的个数。
*/
//标程:
#include<stdio.h>#include<string.h>#include<iostream>using namespace std;#define N 100010struct ss{int l,r,lone,lzero;int rone,rzero,max1,max0;int total,flag0,flag1,flag2,len;}p[10*N];int a[N];int fmax(int x,int y) {return x>y?x:y;}int fmin(int x,int y) {return x<y?x:y;}void pushup(int k){p[k].lone=p[k*2].lone;if(p[2*k].lone==p[2*k].len) p[k].lone+=p[2*k+1].lone;    p[k].lzero=p[2*k].lzero;if(p[2*k].lzero==p[k*2].len)p[k].lzero+=p[2*k+1].lzero;p[k].rone=p[k*2+1].rone;if(p[2*k+1].rone==p[2*k+1].len) p[k].rone+=p[2*k].rone;    p[k].rzero=p[2*k+1].rzero;if(p[2*k+1].rzero==p[k*2+1].len)p[k].rzero+=p[2*k].rzero;p[k].max1=fmax(p[2*k].max1,p[2*k+1].max1);p[k].max1=fmax(p[k].max1,p[2*k].rone+p[2*k+1].lone);p[k].max0=fmax(p[2*k].max0,p[2*k+1].max0);p[k].max0=fmax(p[k].max0,p[2*k].rzero+p[2*k+1].lzero);p[k].total=p[2*k].total+p[2*k+1].total;}void build(int x,int y,int k){p[k].l=x, p[k].r=y, p[k].len=(y-x+1);p[k].flag0=p[k].flag1=p[k].flag2=0;if(x==y){if(a[x]==1){ p[k].max1=p[k].total=p[k].lone=p[k].rone=1; p[k].lzero=p[k].rzero=p[k].max0=0;}else {p[k].max1=p[k].total=p[k].lone=p[k].rone=0;p[k].lzero=p[k].rzero=p[k].max0=1;}return ;}int mid=(x+y)/2;build(x,mid,2*k);build(mid+1,y,2*k+1);pushup(k);}void pushdown(int k,int flag){    if(flag==0){p[2*k].flag0=p[2*k+1].flag0=1;p[2*k].flag1=p[2*k+1].flag1=0;p[2*k].flag2=p[2*k+1].flag2=0;        p[k].flag0=0;p[2*k].lone=p[k*2].rone=p[2*k+1].lone=p[k*2+1].rone=0;p[2*k].total=p[2*k+1].total=0;        p[2*k].max1=p[2*k+1].max1=0;p[2*k].max0=p[2*k].lzero=p[2*k].rzero=p[2*k].len;p[2*k+1].max0=p[2*k+1].lzero=p[k*2+1].rzero=p[2*k+1].len;}else if(flag==1){        p[2*k].flag0=p[2*k+1].flag0=0;p[2*k].flag1=p[2*k+1].flag1=1;p[2*k].flag2=p[2*k+1].flag2=0;        p[k].flag1=0;p[2*k].lzero=p[k*2].rzero=p[2*k+1].lzero=p[k*2+1].rzero=0;        p[2*k].max0=p[2*k+1].max0=0;p[2*k].total=p[2*k].max1=p[2*k].lone=p[2*k].rone=p[2*k].len;p[2*k+1].total=p[2*k+1].max1=p[2*k+1].lone=p[k*2+1].rone=p[2*k+1].len;}else {p[2*k].flag2^=1;p[2*k+1].flag2^=1;p[k].flag2=0;swap(p[2*k].lone,p[2*k].lzero);swap(p[2*k].rone,p[2*k].rzero);        swap(p[2*k].max0,p[2*k].max1);p[2*k].total=p[2*k].len-p[2*k].total;swap(p[2*k+1].lone,p[2*k+1].lzero);swap(p[2*k+1].rone,p[2*k+1].rzero);swap(p[2*k+1].max0,p[2*k+1].max1);p[2*k+1].total=p[2*k+1].len-p[2*k+1].total;}}void Insert(int x,int y,int k,int op){    if(x==p[k].l && y==p[k].r){if(op==0){p[k].flag0=1,  p[k].flag1=p[k].flag2=0;p[k].lone=p[k].rone=0;p[k].max0=p[k].lzero=p[k].rzero=p[k].len;p[k].max1=p[k].total=0;return ;}else if(op==1){p[k].flag1=1, p[k].flag0=p[k].flag2=0;p[k].max0=p[k].lzero=p[k].rzero=0;p[k].total=p[k].max1=p[k].lone=p[k].rone=p[k].len;return ;}else{p[k].flag2=p[k].flag2^1;if(p[k].flag0==1) pushdown(k,0);if(p[k].flag1==1) pushdown(k,1);swap(p[k].lone,p[k].lzero);swap(p[k].rone,p[k].rzero);swap(p[k].max1,p[k].max0);p[k].total=p[k].len-p[k].total;return ;}}if(p[k].l!=p[k].r){if(p[k].flag0==1) pushdown(k,0);if(p[k].flag1==1) pushdown(k,1);if(p[k].flag2==1) pushdown(k,2);}int mid=(p[k].l+p[k].r)/2;if(y<=mid) Insert(x,y,2*k,op);else if(x>mid) Insert(x,y,2*k+1,op);else {Insert(x,mid,2*k,op);Insert(mid+1,y,2*k+1,op);}pushup(k);}int sum1(int x,int y,int k){if(p[k].len==p[k].max1) return y-x+1;if(p[k].len==p[k].max0) return 0;if(x==p[k].l && y==p[k].r) return  p[k].total;if(p[k].l!=p[k].r){if(p[k].flag0==1) pushdown(k,0);if(p[k].flag1==1) pushdown(k,1);if(p[k].flag2==1) pushdown(k,2);}int mid=(p[k].l+p[k].r)/2;if(y<=mid)   sum1(x,y,2*k);else if(x>mid)  sum1(x,y,2*k+1);else  return sum1(x,mid,2*k)+sum1(mid+1,y,2*k+1); }int sum2(int x,int y,int k){    if(p[k].len==p[k].max1) return y-x+1;if(p[k].len==p[k].max0) return 0;if(x==p[k].l && y==p[k].r) return  p[k].max1;    if(p[k].l!=p[k].r){if(p[k].flag0==1) pushdown(k,0);if(p[k].flag1==1) pushdown(k,1);if(p[k].flag2==1) pushdown(k,2);}int mid=(p[k].l+p[k].r)/2;if(y<=mid)  return sum2(x,y,2*k);else if(x>mid) return sum2(x,y,2*k+1);else  {int left=0, right=0,midn=0;midn=midn+fmin(mid-x+1,p[k*2].rone)+fmin(y-mid,p[2*k+1].lone);left=sum2(x,mid,2*k);right=sum2(mid+1,y,2*k+1);return fmax(midn,fmax(left,right));}}int main(){//freopen("a.txt","r",stdin);int t,n,m,i,op,x,y;scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);for(i=1;i<=n;i++) scanf("%d",a+i);build(1,n,1);while(m--){scanf("%d%d%d",&op,&x,&y);if(op==0)  Insert(x+1,y+1,1,op);else if(op==1) Insert(x+1,y+1,1,op);else if(op==2) Insert(x+1,y+1,1,op);else if(op==3) printf("%d\n",sum1(x+1,y+1,1));else if(op==4)   printf("%d\n",sum2(x+1,y+1,1));}}return 0;}