Sequence operation(线段树区间多种操作)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Sequence operation(线段树区间多种操作)相关的知识,希望对你有一定的参考价值。
Sequence operation
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7452 Accepted Submission(s): 2220
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
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
题解:测试数据对了但是一直re。。。。先贴着吧。。。
0,1,2,代表操作,0代表将区间内全部变为0,1代表区间内全部变为1,2代表区间内0,1取反
3,4代表查询,3代表查询区间内1的总数,4代表查询区间内最长连续1的个数
re代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<vector> using namespace std; const int INF=0x3f3f3f3f; #define mem(x,y) memset(x,y,sizeof(x)) #define SI(x) scanf("%d",&x) #define PI(x) printf("%d",x) #define SD(x,y) scanf("%lf%lf",&x,&y) #define P_ printf(" ") #define ll root<<1 #define rr root<<1|1 #define lson ll,l,mid #define rson rr,mid+1,r typedef long long LL; const int MAXN=200010; struct Node{ int len,n0,ln0,rn0,sum,v,lazy,x_or; int n1,ln1,rn1; Node init(){ SI(v); n0=ln0=rn0=(v==0); n1=ln1=rn1=(v==1); sum=v; } }; Node tree[MAXN<<1]; void XOR(int root,int v){ swap(tree[root].n0,tree[root].n1); swap(tree[root].ln0,tree[root].ln1); swap(tree[root].rn0,tree[root].rn1); tree[root].sum=v-tree[root].sum; if(tree[root].lazy!=-1)tree[root].lazy^=1; //printf("%d %d %d %d %d %d\n",tree[root].n0,tree[root].ln0,tree[root].rn0,tree[root].n1,tree[root].ln1,tree[root].rn1); } void pushup(int root){ tree[root].sum=tree[ll].sum+tree[rr].sum; tree[root].ln0=tree[ll].ln0; tree[root].rn0=tree[rr].rn0; if(tree[ll].ln0==tree[ll].len)tree[root].ln0+=tree[rr].ln0; if(tree[rr].rn0==tree[rr].len)tree[root].rn0+=tree[ll].rn0; tree[root].n0=max(max(tree[root].ln0,tree[root].rn0),tree[ll].rn0+tree[rr].ln0); tree[root].ln1=tree[ll].ln1; tree[root].rn1=tree[rr].rn1; if(tree[ll].ln1==tree[ll].len)tree[root].ln1+=tree[rr].ln1; if(tree[rr].rn1==tree[rr].len)tree[root].rn1+=tree[ll].rn1; tree[root].n1=max(max(tree[root].ln1,tree[root].rn1),tree[ll].rn1+tree[rr].ln1); } void pushdown(int root,int v){ if(tree[root].lazy!=-1){ tree[ll].lazy=tree[rr].lazy=tree[root].lazy; tree[ll].ln0=tree[ll].n0=tree[ll].rn0=tree[root].lazy?0:tree[ll].len; tree[rr].ln0=tree[rr].n0=tree[rr].rn0=tree[root].lazy?0:tree[rr].len; tree[rr].ln1=tree[rr].n1=tree[rr].rn1=tree[root].lazy?tree[rr].len:0; tree[ll].ln1=tree[ll].n1=tree[ll].rn1=tree[root].lazy?tree[ll].len:0; tree[ll].sum=tree[root].lazy?tree[ll].len:0; tree[rr].sum=tree[root].lazy?tree[rr].len:0; /* tree[root].sum=v; tree[root].ln0=tree[root].rn0=tree[root].lazy?0:tree[root].len; tree[root].ln1=tree[root].rn1=tree[root].lazy?tree[root].len:0; */ tree[ll].x_or=tree[rr].x_or=0; tree[root].lazy=-1; } if(tree[root].x_or){ tree[ll].x_or^=1; tree[rr].x_or^=1; XOR(ll,tree[ll].len); XOR(rr,tree[rr].len); tree[root].x_or=0; } } void build(int root,int l,int r){ tree[root].len=r-l+1; tree[root].lazy=-1; tree[root].x_or=0; if(l==r){ tree[root].init();return; } int mid=(l+r)>>1; build(lson);build(rson); pushup(root); } void update(int root,int l,int r,int A,int B,int c){ int mid=(l+r)>>1; pushdown(root,tree[root].len); if(l>=A&&r<=B){ //printf("c=%d\n",c); if(c<2){ tree[root].lazy=c; tree[root].sum=tree[root].lazy?tree[root].len:0; tree[root].n0=tree[root].ln0=tree[root].rn0=tree[root].lazy?0:tree[root].len; tree[root].n1=tree[root].ln1=tree[root].rn1=tree[root].lazy?tree[root].len:0; } else{ tree[root].x_or=1; XOR(root,tree[root].len); } return; } pushdown(root,r-l+1); if(mid>=A)update(lson,A,B,c); if(mid<B)update(rson,A,B,c); pushup(root); } int query(int root,int l,int r,int A,int B,int c){ if(l>=A&&r<=B){ // printf("%d %d\n",tree[root].sum,tree[root].n1); if(c==3)return tree[root].sum; else return tree[root].n1; } pushdown(root,r-l+1); int mid=(l+r)>>1; if(mid>=B)return query(lson,A,B,c); else if(mid<A)return query(rson,A,B,c); else{ int ans1=query(lson,A,mid,c); int ans2=query(rson,mid+1,B,c); if(c==3)return ans1+ans2; else return max(max(ans1,ans2),min(mid-A+1,tree[ll].rn1)+min(B-mid,tree[rr].ln1)); } } int main(){ int T,N,M; SI(T); while(T--){ SI(N);SI(M); build(1,0,N-1); while(M--){ int p,a,b; scanf("%d%d%d",&p,&a,&b); if(p<=2)update(1,0,N-1,a,b,p); else{ printf("%d\n",query(1,0,N-1,a,b,p)); } } } return 0; }
以上是关于Sequence operation(线段树区间多种操作)的主要内容,如果未能解决你的问题,请参考以下文章
HDU 3397 Sequence operation(线段树)
线段树 区间合并 F - Sequence operation
hdu 3397 Sequence operation (线段树 区间合并 多重标记)