2017.9.10 序列操作 思考记录

来源:互联网 发布:积家 知乎 编辑:程序博客网 时间:2024/05/22 13:25

唉,怎么说呢、pushdown要注意的事全忘光了、写+调竟然花了两个小时、


要注意反转时是^1而不是=1!

下传标记不要单纯管顺序,因为没有任何意义,要确保在任意时刻一个点只有一种同级标记!!比如赋值和反转就是一级的(顺序可以换)

但加减和乘除是两级的,因为可以规定先加减再乘除、就不会影响了


码(为什么我写的线段树都这么整齐、):

#include<iostream>#include<cstdio>#include<algorithm>using namespace std;#define zuo o<<1,l,mid#define you o<<1|1,mid+1,r#define N 100005int gs1[N<<2],v[N],gs0[N<<2],lx1[N<<2],lx0[N<<2],l1[N<<2],l0[N<<2],ans,ansr,r0[N<<2],r1[N<<2],a,b,op,n,i,m,rev[N<<2],fg1[N<<2],fg0[N<<2];void up(int o,int l,int r){int ll=o<<1,rr=o<<1|1;gs1[o]=gs1[ll]+gs1[rr];gs0[o]=gs0[ll]+gs0[rr];lx1[o]=max(lx1[ll],max(lx1[rr],r1[ll]+l1[rr]));lx0[o]=max(lx0[ll],max(lx0[rr],r0[ll]+l0[rr]));l0[o]=l0[ll];if(l0[ll]==(r+l)/2-l+1)l0[o]=l0[ll]+l0[rr];l1[o]=l1[ll];if(l1[ll]==(r+l)/2-l+1)l1[o]=l1[ll]+l1[rr];r0[o]=r0[rr];if(r0[rr]==r-(r+l)/2)r0[o]=r0[ll]+r0[rr];r1[o]=r1[rr];if(r1[rr]==r-(r+l)/2)r1[o]=r1[ll]+r1[rr];}void down(int o,int l,int r){int ll=o<<1,rr=o<<1|1;if(fg1[o]){fg1[o]=0;fg0[ll]=0;fg0[rr]=0;fg1[ll]=1;fg1[rr]=1;rev[ll]=0;rev[rr]=0;lx1[ll]=l1[ll]=r1[ll]=gs1[ll]=(l+r)/2-l+1;lx0[ll]=l0[ll]=r0[ll]=gs0[ll]=0;lx1[rr]=l1[rr]=r1[rr]=gs1[rr]=r-(l+r)/2;lx0[rr]=l0[rr]=r0[rr]=gs0[rr]=0;}if(fg0[o]){fg0[o]=0;fg0[ll]=1;fg0[rr]=1;fg1[ll]=0;fg1[rr]=0;rev[ll]=0;rev[rr]=0;lx1[ll]=l1[ll]=r1[ll]=gs1[ll]=0;lx0[ll]=l0[ll]=r0[ll]=gs0[ll]=(l+r)/2-l+1;lx1[rr]=l1[rr]=r1[rr]=gs1[rr]=0;lx0[rr]=l0[rr]=r0[rr]=gs0[rr]=r-(l+r)/2;}if(rev[o]){rev[o]=0;rev[ll]^=1;rev[rr]^=1;swap(gs1[ll],gs0[ll]);swap(lx0[ll],lx1[ll]);swap(l0[ll],l1[ll]);swap(r0[ll],r1[ll]);swap(gs1[rr],gs0[rr]);swap(lx0[rr],lx1[rr]);swap(l0[rr],l1[rr]);swap(r0[rr],r1[rr]);}}void jian(int o,int l,int r){if(l==r){  if(v[l]==1)  {  gs1[o]=1;l1[o]=1;r1[o]=1;        lx1[o]=1;  }else   {  gs0[o]=1;  l0[o]=1;  r0[o]=1; lx0[o]=1;    }return ;}int mid=(l+r)>>1;jian(zuo);jian(you);up(o,l,r);}void gai(int o,int l,int r){if(a<=l&&r<=b){if(op==0){fg0[o]=1;fg1[o]=rev[o]=0;gs1[o]=l1[o]=r1[o]=lx1[o]=0;gs0[o]=l0[o]=r0[o]=lx0[o]=r-l+1;}if(op==1){fg1[o]=1;fg0[o]=rev[o]=0;gs1[o]=l1[o]=r1[o]=lx1[o]=r-l+1;gs0[o]=l0[o]=r0[o]=lx0[o]=0;}if(op==2){rev[o]^=1;swap(l0[o],l1[o]);swap(r0[o],r1[o]);swap(lx0[o],lx1[o]);swap(gs0[o],gs1[o]);}if(op==3){ans+=gs1[o];}if(op==4){ans=max(ans,max(lx1[o],ansr+l1[o]));if(l1[o]==r-l+1)ansr+=l1[o];else ansr=r1[o];}return;}down(o,l,r);int mid=(l+r)>>1;if(a<=mid)gai(zuo);if(b>mid)gai(you);up(o,l,r);}int main(){scanf("%d%d",&n,&m);for(i=1;i<=n;i++)scanf("%d",&v[i]);jian(1,1,n);for(i=1;i<=m;i++){scanf("%d",&op);scanf("%d%d",&a,&b);a++;b++;ans=ansr=0;gai(1,1,n);if(op>=3)printf("%d\n",ans);}}