Sequence operation
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6270 Accepted Submission(s): 1862
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
———————————————————————分割线————————————————
题目大意:
给定一个n个数的序列,有5种操作
1: 0 a b 将区间[a,b]覆盖为0
2:1 a b 将区间[a,b]覆盖为1
3:2 a b 将区间[a,b] 0变成1,1变成0
4:3 a b 查询区间[a,b]1的个数
5:4 a b 查询区间[a,b]连续1的个数
思路:
push_up 维护:
左连续,右连续,总连续的0/1的个数
总的1的个数
push_down lazy标记:
覆盖标记,异或标记
当某节点的信息被修改时,要push_up,对于异或标记和覆盖标记 要优先考虑覆盖标记,再考虑异或标记
查找区间的时候要push_down
细节好重要!!!加深理解push_up,push_down
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
const int maxn=100001;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
int lc[maxn<<2],rc[maxn<<2],mc[maxn<<2];
int lc0[maxn<<2],rc0[maxn<<2],mc0[maxn<<2];
int cov[maxn<<2],Xor[maxn<<2],sum[maxn<<2];
void f_xor(int rt,int m)
{
if(cov[rt]!=-1) cov[rt]^=1;
else Xor[rt]^=1;
swap(lc[rt],lc0[rt]);
swap(rc[rt],rc0[rt]);
swap(mc[rt],mc0[rt]);
sum[rt]=m-sum[rt];
}
void f_cov(int rt,int m,int c)
{
cov[rt]=c;
Xor[rt]=0;
lc0[rt]=rc0[rt]=mc0[rt]=c ?0:m;
lc[rt]=rc[rt]=mc[rt]=sum[rt]=c ? m:0;
}
void push_down(int rt,int m)
{
if(cov[rt]!=-1) {
f_cov(rt<<1,m-(m>>1),cov[rt]);
f_cov(rt<<1|1,m>>1,cov[rt]);
cov[rt]=-1;
Xor[rt]=0;
}
if(Xor[rt]) {
f_xor(rt<<1,m-(m>>1));
f_xor(rt<<1|1,m>>1);
Xor[rt]=0;
}
}
void push_up(int rt,int m)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
lc[rt]=lc[rt<<1];
rc[rt]=rc[rt<<1|1];
if(lc[rt]==m-(m>>1))
lc[rt]+=lc[rt<<1|1];
if(rc[rt]==m>>1)
rc[rt]+=rc[rt<<1];
mc[rt]=max(rc[rt<<1]+lc[rt<<1|1],max(mc[rt<<1],mc[rt<<1|1]));
lc0[rt]=lc0[rt<<1];
rc0[rt]=rc0[rt<<1|1];
if(lc0[rt]==m-(m>>1))
lc0[rt]+=lc0[rt<<1|1];
if(rc0[rt]==m>>1)
rc0[rt]+=rc0[rt<<1];
mc0[rt]=max(lc0[rt<<1|1]+rc0[rt<<1],max(mc0[rt<<1],mc0[rt<<1|1]));
}
void build(int l,int r,int rt)
{
cov[rt]=-1;
Xor[rt]=0;
if(l==r) {
scanf("%d",&sum[rt]);
cov[rt]=lc[rt]=rc[rt]=mc[rt]=sum[rt];
lc0[rt]=rc0[rt]=mc0[rt]= 1-sum[rt];
return ;
}
int m=(l+r)>>1;
build(lson);
build(rson);
push_up(rt,r-l+1);
}
void update(int op,int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R) {
if(op==0)
f_cov(rt,r-l+1,0);
if(op==1)
f_cov(rt,r-l+1,1);
if(op==2)
f_xor(rt,r-l+1);
return ;
}
push_down(rt,r-l+1);
int m=(l+r)>>1;
if(L<=m) update(op,L,R,lson);
if(m<R) update(op,L,R,rson);
push_up(rt,r-l+1);
}
int query_sum(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R) {
return sum[rt];
}
push_down(rt,r-l+1);
int m=(l+r)>>1;
int ans=0;
if(L<=m)
ans+=query_sum(L,R,lson);
if(m<R)
ans+=query_sum(L,R,rson);
return ans;
}
int query_len(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R) {
return mc[rt];
}
push_down(rt,r-l+1);
int m=(l+r)>>1;
int ans=0;
if(L<=m)
ans=max(ans,query_len(L,R,lson));
if(m<R)
ans=max(ans,query_len(L,R,rson));
return max(ans,min(m-L+1,rc[rt<<1])+min(R-m,lc[rt<<1|1]));
}
int main()
{
int T,n,m;
cin>>T;
while(T--) {
scanf("%d %d",&n,&m);
build(0,n-1,1);
int op,l,r;
while(m--) {
scanf("%d %d %d",&op,&l,&r);
if(op<=2)
update(op,l,r,0,n-1,1);
if(op==3)
printf("%d\n",query_sum(l,r,0,n-1,1));
if(op==4)
printf("%d\n",query_len(l,r,0,n-1,1));
}
}
return 0;
}