Sequence operation
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 8568 Accepted Submission(s): 2593
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]
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.
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
1 10 10 0 0 0 1 1 0 1 0 1 1 1 0 2 3 0 5 2 2 2 4 0 4 0 3 6 2 3 7 4 2 8 1 0 5 0 5 6 3 3 9
Sample Output
5 2 6 5
这里Push_down要格外注意,add[rt]实际上表示的是需要更新的
子树,所以要防止add[lson]的值被覆盖的情况。
代码:
#include<cstdio>
#include<string.h>
#include<algorithm>
using namespace std;
#define lson rt<<1
#define rson rt<<1|1
const int maxn=1e5+7;
int a[maxn],add[maxn<<2];
struct node
{
int left,right,mid;
int lx0,rx0,mx0;
int lx1,rx1,mx1;
int dis()
{
return right-left+1;
}
int num;
} c[maxn<<2];
int pp(int op,int rt)
{
if(add[rt]==-1)return op;
if(op==1) return 1;
if(op==0) return 0;
if(op==2&&add[rt]==2) return -1;
return add[rt]^1;
}
void change(int op,int rt)
{
if(op==0)
{
c[rt].lx0=c[rt].rx0=c[rt].mx0=c[rt].dis();
c[rt].lx1=c[rt].rx1=c[rt].mx1=0;
c[rt].num=0;
}
else if(op==1)
{
c[rt].lx0=c[rt].rx0=c[rt].mx0=0;
c[rt].lx1=c[rt].rx1=c[rt].mx1=c[rt].dis();
c[rt].num=c[rt].dis();
}
else
{
swap(c[rt].lx0,c[rt].lx1);
swap(c[rt].rx0,c[rt].rx1);
swap(c[rt].mx0,c[rt].mx1);
c[rt].num=c[rt].dis()-c[rt].num;
}
}
void Push_down(int rt)
{
if(c[rt].left==c[rt].right)
return;
int op=add[rt];
if(op==-1)return;
add[rt]=-1;
add[lson]=pp(op,lson);
add[rson]=pp(op,rson);
change(op,lson);
change(op,rson);
}
void Push_up(int rt)
{
c[rt].lx0=c[lson].lx0;
if(c[lson].lx0==c[lson].dis())
c[rt].lx0+=c[rson].lx0;
c[rt].rx0=c[rson].rx0;
if(c[rson].rx0==c[rson].dis())
c[rt].rx0+=c[lson].rx0;
c[rt].mx0=max(max(c[lson].mx0,c[rson].mx0),c[lson].rx0+c[rson].lx0);
c[rt].lx1=c[lson].lx1;
if(c[lson].lx1==c[lson].dis())
c[rt].lx1+=c[rson].lx1;
c[rt].rx1=c[rson].rx1;
if(c[rson].rx1==c[rson].dis())
c[rt].rx1+=c[lson].rx1;
c[rt].mx1=max(max(c[lson].mx1,c[rson].mx1),c[lson].rx1+c[rson].lx1);
c[rt].num=c[lson].num+c[rson].num;
}
void build(int l,int r,int rt)
{
c[rt].left=l;
c[rt].right=r;
c[rt].mid=(l+r)>>1;
if(l==r)
{
c[rt].lx0=c[rt].rx0=c[rt].mx0=a[l]^1;
c[rt].lx1=c[rt].rx1=c[rt].mx1=a[l];
c[rt].num=a[l];
return;
}
build(l,c[rt].mid,lson);
build(c[rt].mid+1,r,rson);
Push_up(rt);
}
void update(int op,int l,int r,int rt)
{
Push_down(rt);
if(l==c[rt].left&&r==c[rt].right)
{
add[rt]=op;
//pp(op,add[rt]);
//if(add[rt]!=-1)
change(op,rt);
return;
}
if(r<=c[rt].mid) update(op,l,r,lson);
else if(l>c[rt].mid) update(op,l,r,rson);
else
{
update(op,l,c[rt].mid,lson);
update(op,c[rt].mid+1,r,rson);
}
Push_up(rt);
}
int query(int op,int l,int r,int rt)
{
Push_down(rt);
if(l==c[rt].left&&r==c[rt].right)
{
if(op==3)return c[rt].num;
return c[rt].mx1;
}
if(r<=c[rt].mid)return query(op,l,r,lson);
else if(l>c[rt].mid)return query(op,l,r,rson);
else
{
int ll,rr,mm;
ll=query(op,l,c[rt].mid,lson);
rr=query(op,c[rt].mid+1,r,rson);
if(op==3)return ll+rr;
else
{
mm=min(c[rt].mid-l+1,c[lson].rx1)+min(r-c[rt].mid,c[rson].lx1);
return max(max(ll,rr),mm);
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,m,i,j;
memset(add,-1,sizeof(add));
scanf("%d%d",&n,&m);
for(i=1; i<=n; i++)
scanf("%d",&a[i]);
build(1,n,1);
while(m--)
{
int op,x,y;
scanf("%d%d%d",&op,&x,&y);
if(op<3) update(op,x+1,y+1,1);
else printf("%d\n",query(op,x+1,y+1,1));
}
}
return 0;
}