点击打开题目链接,还有一个类似的题,只进行01翻转操作和最大连续查询,HDU3911 Black And White
对一个数列进行如下操作:
Change operations:
0 a b change all characters into '0's in [a , b]4 a b output the length of the longest continuous '1' string in [a , b]
区间属性
1.最大连续长度=Max(左区间最大,有区间最大,左区间右起最大+有区间左起最大)
2.左端点开始的最大连续长度=左区间最大左连续 或 左区间长度+右区间最大左连续(如果左区间最大左连续==左区间长度)
3.有端点开始的最大连续长度,同上;
注意:
1. 所有翻转的flag都要用 ^操作,避免连续翻转两次而未更新的区间。
2.全置的优先级高于翻转
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.StreamTokenizer; public class Main{ class SegTree{ class node{ int left,right; int flag,num0,num1; int max0,l0,r0; int max1,l1,r1; int mid(){ return (left+right)>>1; } int length(){ return right-left+1; } void init(int k){ if(k==0){ num0=max0=l0=r0=length(); num1=l1=r1=max1=0; } else { max1=l1=r1=num1=length(); num0=max0=l0=r0=0; } } } node tree[]; SegTree(int maxn){ tree=new node[maxn*5]; } void init(int left,int right,int idx,int[]a){ tree[idx]=new node(); tree[idx].left=left; tree[idx].right=right; tree[idx].flag=-1; if(left==right){ tree[idx].init(a[left]); return; } int mid=tree[idx].mid(); init(left,mid,idx<<1,a); init(mid+1,right,(idx<<1)|1,a); pushup(idx); } void update(int left,int right,int idx,int op){ pushdown(idx); if(tree[idx].left>=left&&tree[idx].right<=right){ if(op==2) reverse(idx); else tree[idx].flag=op; return; } int mid=tree[idx].mid(); if(left<=mid) update(left,right,idx<<1,op); if(right>mid) update(left,right,(idx<<1)|1,op); pushup(idx); } int query(int left,int right,int idx,int type) { pushdown(idx); if(tree[idx].left==left&&tree[idx].right==right){ if(type==3) return tree[idx].num1; else return tree[idx].max1; } int mid=tree[idx].mid(); if(right<=mid) return query(left,right,idx<<1,type); else if(left>mid) return query(left,right,(idx<<1)|1,type); else{ int a=query(left,mid,idx<<1,type); int b=query(mid+1,right,(idx<<1)|1,type); if(type==3) return a+b; int c = Math.min(tree[idx << 1].r1, mid - left + 1) + Math.min(tree[(idx << 1) | 1].l1, right - mid); return Math.max(Math.max(a,b),c); } } void pushup(int idx){ if(tree[idx].left==tree[idx].right) return; pushdown(idx<<1); pushdown((idx<<1)|1); tree[idx].num1=tree[idx<<1].num1+tree[(idx<<1)|1].num1; tree[idx].num0=tree[idx<<1].num0+tree[(idx<<1)|1].num0; int a=tree[idx<<1].max0; int b=tree[(idx<<1)|1].max0; int c=tree[idx<<1].r0+tree[(idx<<1)|1].l0; tree[idx].max0=Math.max(Math.max(a,b), c); tree[idx].l0=tree[idx<<1].l0; if(tree[idx].l0==tree[idx<<1].length()) tree[idx].l0+=tree[(idx<<1)|1].l0; tree[idx].r0=tree[(idx<<1)|1].r0; if(tree[(idx<<1)|1].r0==tree[(idx<<1)|1].length()) tree[idx].r0+=tree[idx<<1].r0; a=tree[idx<<1].max1; b=tree[(idx<<1)|1].max1; c=tree[idx<<1].r1+tree[(idx<<1)|1].l1; tree[idx].max1=Math.max(Math.max(a,b), c); tree[idx].l1=tree[idx<<1].l1; if(tree[idx].l1==tree[idx<<1].length()) tree[idx].l1+=tree[(idx<<1)+1].l1; tree[idx].r1=tree[(idx<<1)|1].r1; if(tree[(idx<<1)|1].r1==tree[(idx<<1)|1].length()) tree[idx].r1+=tree[idx<<1].r1; } void pushdown(int idx){ if(tree[idx].flag==2){ int t=tree[idx].l0; tree[idx].l0=tree[idx].l1; tree[idx].l1=t; t=tree[idx].r0; tree[idx].r0=tree[idx].r1; tree[idx].r1=t; t=tree[idx].max0; tree[idx].max0=tree[idx].max1; tree[idx].max1=t; tree[idx].flag=-1; t=tree[idx].num0; tree[idx].num0=tree[idx].num1; tree[idx].num1=t; if(tree[idx].left!=tree[idx].right){ t=idx<<1; reverse(t); t++; reverse(t); } } if(tree[idx].flag==1||tree[idx].flag==0){ int t=tree[idx].flag; tree[idx].init(t); tree[idx].flag=-1; if(tree[idx].left!=tree[idx].right){ tree[idx<<1].flag=t; tree[(idx<<1)|1].flag=t; } } } void reverse(int idx){ if(tree[idx].flag==2) tree[idx].flag=-1; else if(tree[idx].flag==-1) tree[idx].flag=2; else tree[idx].flag^=1; } } StreamTokenizer in = new StreamTokenizer(new BufferedReader( new InputStreamReader(System.in))); final int next() throws IOException { in.nextToken(); return (int) in.nval; } SegTree st=new SegTree(100010); int a[]=new int[100010]; void run() throws IOException{ int t=next(); while(t-->0){ int n=next(); int m=next(); for(int i=1;i<=n;i++) a[i]=next(); st.init(1, n, 1, a); while(m-->0){ int k=next(); int a=next()+1; int b=next()+1; if(k<3) st.update(a, b, 1, k); else System.out.println(st.query(a, b, 1, k)); } } } public static void main(String[] args) throws IOException { new Main().run(); } }