解题:SCOI 2010 序列操作

题面

线段树......模板题(雾?

然而两种标记会互相影响,必须保证每次只放一个(不然就不知道怎么放了),具体的影响就是:

翻转标记会使得覆盖标记一起翻转,下放的时候就是各种swap

覆盖标记会抹掉翻转标记,下放的时候好像挺正常的

然后就是码码码+细节

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 using namespace std;
  5 const int N=100005;
  6 struct a{int ll,rr,vv;};
  7 int val[4*N],last[4*N][2],lst[4*N][2],rst[4*N][2];
  8 int num[N],laz1[4*N],laz2[4*N];
  9 int n,m,t1,t2,t3;
 10 void pushup(int nde,int l,int r)
 11 {
 12     int mid=(l+r)/2,ls=2*nde,rs=2*nde+1;
 13     val[nde]=val[ls]+val[rs];
 14     //value
 15     lst[nde][1]=(last[ls][1]==mid-l+1)?last[ls][1]+lst[rs][1]:lst[ls][1];
 16     rst[nde][1]=(last[rs][1]==r-mid)?last[rs][1]+rst[ls][1]:rst[rs][1];
 17     last[nde][1]=max(rst[ls][1]+lst[rs][1],max(last[ls][1],last[rs][1]));
 18     //longest continuing one
 19     lst[nde][0]=(last[ls][0]==mid-l+1)?last[ls][0]+lst[rs][0]:lst[ls][0];
 20     rst[nde][0]=(last[rs][0]==r-mid)?last[rs][0]+rst[ls][0]:rst[rs][0];
 21     last[nde][0]=max(rst[ls][0]+lst[rs][0],max(last[ls][0],last[rs][0]));
 22     //longest continuing zero
 23 }
 24 void create(int nde,int l,int r)
 25 {
 26     if(l==r)
 27     {
 28         last[nde][0]=lst[nde][0]=rst[nde][0]=(num[l]^1);
 29         val[nde]=last[nde][1]=lst[nde][1]=rst[nde][1]=num[l];
 30     }
 31     else
 32     {
 33         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1;
 34         create(ls,l,mid),create(rs,mid+1,r);
 35         pushup(nde,l,r);
 36     }
 37 }
 38 void release(int nde,int l,int r)
 39 {
 40     int mid=(l+r)/2,ls=2*nde,rs=2*nde+1;
 41     if(laz2[nde])
 42     {
 43         if(~laz1[ls]) laz1[ls]^=1; else laz2[ls]^=1;
 44         if(~laz1[rs]) laz1[rs]^=1; else laz2[rs]^=1;
 45         val[ls]=(mid-l+1)-val[ls],val[rs]=(r-mid)-val[rs];
 46         //reversing
 47         swap(last[ls][0],last[ls][1]),swap(last[rs][0],last[rs][1]);
 48         swap(lst[ls][0],lst[ls][1]),swap(lst[rs][0],lst[rs][1]);
 49         swap(rst[ls][0],rst[ls][1]),swap(rst[rs][0],rst[rs][1]);
 50         //a lot of swaps......
 51         laz2[nde]=0;
 52         //refresh
 53     }
 54     //release the lazy tag of intervals reversing
 55     else if(~laz1[nde])
 56     {
 57         laz1[ls]=laz1[nde],laz1[rs]=laz1[nde],laz2[ls]=0,laz2[rs]=0;
 58         //to the left/right son
 59         val[ls]=last[ls][1]=lst[ls][1]=rst[ls][1]=(mid-l+1)*laz1[nde];
 60         val[rs]=last[rs][1]=lst[rs][1]=rst[rs][1]=(r-mid)*laz1[nde]; 
 61         //longest continuing one
 62         last[ls][0]=lst[ls][0]=rst[ls][0]=(mid-l+1)*(laz1[nde]^1);
 63         last[rs][0]=lst[rs][0]=rst[rs][0]=(r-mid)*(laz1[nde]^1); 
 64         //longest continuing zero
 65         laz1[nde]=-1;
 66         //refresh
 67     }
 68     //release the lazy tag of intervals covering
 69 }
 70 void Change(int nde,int l,int r,int nl,int nr,int task)
 71 {
 72     if(l>nr||r<nl)
 73         return ;
 74     else if(l>=nl&&r<=nr)
 75     {
 76         last[nde][0]=lst[nde][0]=rst[nde][0]=(task^1)*(r-l+1);
 77         val[nde]=last[nde][1]=lst[nde][1]=rst[nde][1]=task*(r-l+1);
 78         laz1[nde]=task,laz2[nde]=0;
 79     }
 80     else
 81     {
 82         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; release(nde,l,r);
 83         Change(ls,l,mid,nl,nr,task),Change(rs,mid+1,r,nl,nr,task);
 84         pushup(nde,l,r); 
 85     }
 86 }
 87 void Reverse(int nde,int l,int r,int nl,int nr)
 88 {
 89     if(l>nr||r<nl)
 90         return ;
 91     else if(l>=nl&&r<=nr)
 92     {
 93         val[nde]=(r-l+1)-val[nde],swap(last[nde][0],last[nde][1]);
 94         swap(lst[nde][0],lst[nde][1]),swap(rst[nde][0],rst[nde][1]);
 95         if(~laz1[nde]) laz1[nde]^=1; else laz2[nde]^=1;
 96     }
 97     else
 98     {
 99         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; release(nde,l,r);
100         Reverse(ls,l,mid,nl,nr),Reverse(rs,mid+1,r,nl,nr); pushup(nde,l,r); 
101     }
102 }
103 int Vquery(int nde,int l,int r,int nl,int nr)
104 {
105     if(l>nr||r<nl)
106         return 0;
107     else if(l>=nl&&r<=nr)
108         return val[nde];
109     else
110     {
111         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; release(nde,l,r);
112         return Vquery(ls,l,mid,nl,nr)+Vquery(rs,mid+1,r,nl,nr);
113     }
114 }
115 a Lquery(int nde,int l,int r,int nl,int nr)
116 {
117     if(l>=nl&&r<=nr)
118         return (a){lst[nde][1],rst[nde][1],last[nde][1]};
119     else
120     {
121         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; release(nde,l,r);
122         if(nr<=mid) return Lquery(ls,l,mid,nl,nr);
123         if(nl>mid) return Lquery(rs,mid+1,r,nl,nr); 
124         a Q1=Lquery(ls,l,mid,nl,nr),Q2=Lquery(rs,mid+1,r,nl,nr),ret;
125         ret.vv=max(max(Q1.vv,Q2.vv),Q1.rr+Q2.ll);
126         ret.ll=(Q1.vv==(mid-l+1))?Q1.vv+Q2.ll:Q1.ll;
127         ret.rr=(Q2.vv==(r-mid))?Q2.vv+Q1.rr:Q2.rr;
128         return ret;
129     }
130 }
131 int main ()
132 {
133     scanf("%d%d",&n,&m);
134     for(int i=1;i<=n;i++)
135         scanf("%d",&num[i]);
136     create(1,1,n);
137     memset(laz1,-1,sizeof laz1);
138     for(int i=1;i<=m;i++)
139     {
140         scanf("%d%d%d",&t1,&t2,&t3),t2++,t3++;
141         if(!t1) Change(1,1,n,t2,t3,0);
142         else if(t1==1) Change(1,1,n,t2,t3,1);
143         else if(t1==2) Reverse(1,1,n,t2,t3);
144         else if(t1==3) printf("%d
",Vquery(1,1,n,t2,t3));
145         else printf("%d
",Lquery(1,1,n,t2,t3).vv);
146     }
147     return 0;
148 }
View Code
原文地址:https://www.cnblogs.com/ydnhaha/p/9729664.html