bzoj1858: [Scoi2010]序列操作
lazy-tag线段树。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn = 800000 + 10; struct Segtree { #define lc(x) ((x)<<1) #define rc(x) (((x)<<1)|1) int l[maxn],r[maxn]; int l1[maxn],r1[maxn],con1[maxn],cnt1[maxn]; int l0[maxn],r0[maxn],con0[maxn]; int t1[maxn],t0[maxn],tr[maxn]; void set1(int x) { l1[x]=r1[x]=con1[x]=cnt1[x]=r[x]-l[x]+1; l0[x]=r0[x]=con0[x]=0; t1[x]=1; t0[x]=tr[x]=0; } void set0(int x) { l0[x]=r0[x]=con0[x]=r[x]-l[x]+1; l1[x]=r1[x]=con1[x]=cnt1[x]=0; t0[x]=1; t1[x]=tr[x]=0; } void inv(int x) { swap(l1[x],l0[x]); swap(r1[x],r0[x]); swap(con1[x],con0[x]); cnt1[x]=r[x]-l[x]+1-cnt1[x]; tr[x]^=1; } void push(int x) { if(t0[x]) { set0(lc(x)); set0(rc(x)); t0[x]=0; } if(t1[x]) { set1(lc(x)); set1(rc(x)); t1[x]=0; } if(tr[x]) { inv(lc(x)); inv(rc(x)); tr[x]=0; } } void update(int x) { l1[x]=(l1[lc(x)]==r[lc(x)]-l[lc(x)]+1?l1[lc(x)]+l1[rc(x)]:l1[lc(x)]); r1[x]=(r1[rc(x)]==r[rc(x)]-l[rc(x)]+1?r1[rc(x)]+r1[lc(x)]:r1[rc(x)]); l0[x]=(l0[lc(x)]==r[lc(x)]-l[lc(x)]+1?l0[lc(x)]+l0[rc(x)]:l0[lc(x)]); r0[x]=(r0[rc(x)]==r[rc(x)]-l[rc(x)]+1?r0[rc(x)]+r0[lc(x)]:r0[rc(x)]); con1[x]=max(max(con1[lc(x)],con1[rc(x)]),r1[lc(x)]+l1[rc(x)]); con0[x]=max(max(con0[lc(x)],con0[rc(x)]),r0[lc(x)]+l0[rc(x)]); cnt1[x]=cnt1[lc(x)]+cnt1[rc(x)]; } void op0(int x,int L,int R) { push(x); if(R<l[x] || L>r[x]) return; if(L<=l[x] && r[x]<=R) { set0(x); return; } op0(lc(x),L,R); op0(rc(x),L,R); update(x); } void op1(int x,int L,int R) { push(x); if(R<l[x] || L>r[x]) return; if(L<=l[x] && r[x]<=R) { set1(x); return; } op1(lc(x),L,R); op1(rc(x),L,R); update(x); } void op2(int x,int L,int R) { push(x); if(R<l[x] || L>r[x]) return; if(L<=l[x] && r[x]<=R) { inv(x); return; } op2(lc(x),L,R); op2(rc(x),L,R); update(x); } int op3(int x,int L,int R) { push(x); if(R<l[x] || L>r[x]) return 0; if(L<=l[x] && r[x]<=R) return cnt1[x]; return(op3(lc(x),L,R)+op3(rc(x),L,R)); } int op4(int x,int L,int R) { push(x); if(R<l[x] || L>r[x]) return 0; if(L<=l[x] && r[x]<=R) return con1[x]; return max(max(op4(lc(x),L,R),op4(rc(x),L,R)),min(r1[lc(x)],r[lc(x)]-L+1)+min(l1[rc(x)],R-l[rc(x)]+1)); } void build(int x,int L,int R) { l[x]=L; r[x]=R; if(L==R) { int k; scanf("%d",&k); if(k) l1[x]=r1[x]=con1[x]=cnt1[x]=1; else l0[x]=r0[x]=con0[x]=1; return; } int mid=(L+R)>>1; build(lc(x),L,mid); build(rc(x),mid+1,R); update(x); } }seg; int n,m; int main() { scanf("%d%d",&n,&m); seg.build(1,0,n-1); for(int i=1,op,a,b;i<=m;i++) { scanf("%d%d%d",&op,&a,&b); if(op==0) seg.op0(1,a,b); else if(op==1) seg.op1(1,a,b); else if(op==2) seg.op2(1,a,b); else if(op==3) printf("%d\n",seg.op3(1,a,b)); else if(op==4) printf("%d\n",seg.op4(1,a,b)); } return 0; }