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 descriptionlxhgww 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]
Inputt (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.
Outputfor 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
-----------------------Split line----------------
Question:
Five operations are available for a sequence of N numbers.
1: 0 a B overwrites the range [a, B] to 0
A B overwrites the range [a, B] to 1
A B: Change the range [a, B] 0 to 1, 1, and 0.
A B query the number of intervals [a, B] 1
A B The number of consecutive 1 rows in the query interval [a, B]
Ideas:
Push_up maintenance:
Left Continuous, right continuous, the total number of consecutive 0/1
Total number of 1
Push_down lazy flag:
Overwrite mark, exclusive or mark
When the information of a node is modified, push_up is required. For an exclusive or flag or overwrite mark, overwrite mark is preferred, and then an exclusive or flag is considered.
Push_down is required for Interval search
The details are important !!! Deepen understanding of push_up and 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|1using 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;}
HDU 3397 -- sequence operation (line segment tree, interval coloring + interval exclusive or + interval merging)