[bzoj1858]序列操作

考虑建立一棵线段树,维护:1.左端点的连续1和;2.右端点的连续1和;3.最长1的连续子序列;4.1的个数;5.将0和1交换后上面的四项;6.懒标记
具体实现中,需要注意细节,可以看代码(比较短)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 100005
 4 #define L (k<<1)
 5 #define R (L+1)
 6 #define mid (l+r>>1)
 7 struct ji{
 8     int sum,ls,rs,ans;
 9 }f0[N<<2],f1[N<<2];
10 int n,m,p,x,y,laz[N<<2];
11 ji merge(ji x,ji y){
12     if (x.sum<0)return y;
13     if (y.sum<0)return x; 
14     ji z;
15     z.sum=x.sum+y.sum;
16     z.ls=x.ls+((x.ls==x.sum)&&(x.rs==x.sum)&&(x.sum))*y.ls;
17     z.rs=y.rs+((y.rs==y.sum)&&(y.ls==y.sum)&&(y.sum))*x.rs;
18     z.ans=max(max(x.ans,y.ans),x.rs+y.ls);
19     return z;
20 }
21 int merge(int x,int y){
22     if ((x<0)||(y<0))return x+y+1;
23     if ((x==2)&&(y==2))return -1;
24     if (x==2)return y^1;
25     return x;
26 }
27 void upd(int k,int l,int r,int x){
28     if (x<0)return;
29     if (x<2){
30         laz[k]=x;
31         f0[k].sum=f0[k].ls=f0[k].rs=f0[k].ans=(x^1)*(r-l+1);
32         f1[k].sum=f1[k].ls=f1[k].rs=f1[k].ans=x*(r-l+1);
33         return;
34     }
35     swap(f0[k],f1[k]);
36     if (laz[k]<0)laz[k]=2;
37     else
38         if (laz[k]>1)laz[k]=-1;
39         else laz[k]^=1;
40 }
41 void up(int k,int l,int r){
42     f0[k]=merge(f0[L],f0[R]);
43     f1[k]=merge(f1[L],f1[R]);
44     upd(k,l,r,-1);
45 }
46 void down(int k,int l,int r){
47     if (laz[k]<0)return;
48     upd(L,l,mid,laz[k]);
49     upd(R,mid+1,r,laz[k]);
50     laz[k]=-1;
51 }
52 void update(int k,int l,int r,int x,int y,int z){
53     if ((l>y)||(x>r))return;
54     if ((x<=l)&&(r<=y)){
55         upd(k,l,r,z);
56         return;
57     }
58     down(k,l,r);
59     update(L,l,mid,x,y,z);
60     update(R,mid+1,r,x,y,z);
61     up(k,l,r);
62 }
63 ji query(int k,int l,int r,int x,int y){
64     if ((l>y)||(x>r))return ji{-1,0,0,0};
65     if ((x<=l)&&(r<=y))return f1[k];
66     down(k,l,r);
67     return merge(query(L,l,mid,x,y),query(R,mid+1,r,x,y));
68 }
69 int main(){
70     scanf("%d%d",&n,&m);
71     for(int i=1;i<=n;i++){
72         scanf("%d",&x);
73         update(1,1,n,i,i,x);
74     }
75     for(int i=1;i<=m;i++){
76         scanf("%d%d%d",&p,&x,&y);
77         x++,y++;
78         if (p<3)update(1,1,n,x,y,p);
79         else{
80             ji o=query(1,1,n,x,y);
81             if (p==3)printf("%d
",o.sum);
82             if (p==4)printf("%d
",o.ans);
83         }
84     }
85 }
View Code
原文地址:https://www.cnblogs.com/PYWBKTDA/p/11869401.html