线段树——BZOJ1858/Luogu2572 [SCOI2010]序列操作

来源:互联网 发布:国外p2p下载软件 编辑:程序博客网 时间:2024/06/06 00:08

题面:Luogu2572 BZOJ1858
(傻逼)题?
我不会告诉你我写了调了一个晚上才A掉。。。(逃
思路真的挺简(sha)单(bi),其实就是线段树维护区间和,区间最长连续段。
但是细节实在太多。。。代码太难写。。。
首先关于这个标记的问题,覆盖标记的优先级比反转的高,所以我们一旦加上覆盖标记之后,这个节点之前有的标记都可以清除掉了。。。
还有,如果在这个节点加上反转标记的时候,这个节点有覆盖标记,那就把覆盖标记反转即可,这个反转标记就不必下传了。
然后就是一系列的细节问题了。。。比如合并下传之类的难写难调的东西。。。
最后献上4k代码。。。

#include <cstdio>#include <algorithm>#include <cmath>#include <cstring>#include <iostream>#include <ctime>#include <map>#include <queue>#include <cstdlib>#include <string>#include <climits>#include <set>#include <vector>using namespace std;struct tree{    int lt,rt,sum[2],ls[2],rs[2],ss[2],ro,a[2];    inline void pre(){lt=rt=sum[0]=sum[1]=ls[0]=ls[1]=rs[0]=rs[1]=ss[0]=ss[1]=ro=a[0]=a[1]=0;}}t[400010]; tree operator +(tree a,tree b){    tree c;c.pre();    c.lt=a.lt;c.rt=b.rt;    for(int i=0;i<2;i++){        c.sum[i]=a.sum[i]+b.sum[i];        if(a.ls[i]==a.rt-a.lt+1)c.ls[i]=a.ls[i]+b.ls[i];else c.ls[i]=a.ls[i];        if(b.rs[i]==b.rt-b.lt+1)c.rs[i]=b.rs[i]+a.rs[i];else c.rs[i]=b.rs[i];        c.ss[i]=max(max(a.ss[i],b.ss[i]),a.rs[i]+b.ls[i]);    }    return c;}int n,m,a[100010];inline void jh(int nod){    swap(t[nod].sum[0],t[nod].sum[1]);    swap(t[nod].ls[0],t[nod].ls[1]);    swap(t[nod].rs[0],t[nod].rs[1]);    swap(t[nod].ss[0],t[nod].ss[1]);}inline void pushdown(int nod){    if(t[nod].lt==t[nod].rt){t[nod].ro=t[nod].a[0]=t[nod].a[1]=0;return;}    for(int i=0;i<2;i++)if(t[nod].a[i]){        t[nod*2].sum[i]=t[nod*2].ls[i]=t[nod*2].rs[i]=t[nod*2].ss[i]=t[nod*2].rt-t[nod*2].lt+1;        t[nod*2].sum[i^1]=t[nod*2].ls[i^1]=t[nod*2].rs[i^1]=t[nod*2].ss[i^1]=0;        t[nod*2+1].sum[i]=t[nod*2+1].ls[i]=t[nod*2+1].rs[i]=t[nod*2+1].ss[i]=t[nod*2+1].rt-t[nod*2+1].lt+1;        t[nod*2+1].sum[i^1]=t[nod*2+1].ls[i^1]=t[nod*2+1].rs[i^1]=t[nod*2+1].ss[i^1]=0;        t[nod*2].a[i]=t[nod*2+1].a[i]=1;        t[nod*2].a[i^1]=t[nod*2+1].a[i^1]=t[nod*2].ro=t[nod*2+1].ro=0;              t[nod].a[i]=0;    }    if(t[nod].ro){        t[nod*2].ro^=1;t[nod*2+1].ro^=1;        jh(nod*2);jh(nod*2+1);        if(t[nod*2].a[0]||t[nod*2].a[1])swap(t[nod*2].a[0],t[nod*2].a[1]),t[nod*2].ro=0;        if(t[nod*2+1].a[0]||t[nod*2+1].a[1])swap(t[nod*2+1].a[0],t[nod*2+1].a[1]),t[nod*2+1].ro=0;        t[nod].ro=0;    }}inline void build(int l,int r,int nod){    t[nod].pre();    t[nod].lt=l;t[nod].rt=r;    if(l==r){        t[nod].sum[a[l]]=t[nod].ls[a[l]]=t[nod].rs[a[l]]=t[nod].ss[a[l]]=1;        return;    }    int mid=l+r>>1;    build(l,mid,nod*2);build(mid+1,r,nod*2+1);    t[nod]=t[nod*2]+t[nod*2+1];}inline void xg(int i,int j,int z,int nod){    pushdown(nod);    if(t[nod].lt>=i&&t[nod].rt<=j){        if(t[nod].a[z])return;        t[nod].sum[z]=t[nod].ls[z]=t[nod].rs[z]=t[nod].ss[z]=t[nod].rt-t[nod].lt+1;        t[nod].sum[z^1]=t[nod].ls[z^1]=t[nod].rs[z^1]=t[nod].ss[z^1]=0;        t[nod].a[z]=1;t[nod].ro=t[nod].a[z^1]=0;                return;    }    int mid=t[nod].lt+t[nod].rt>>1;    if(i<=mid)xg(i,j,z,nod*2);    if(j>mid)xg(i,j,z,nod*2+1);    t[nod]=t[nod*2]+t[nod*2+1];}inline void ro(int i,int j,int nod){    pushdown(nod);    if(t[nod].lt>=i&&t[nod].rt<=j){        t[nod].ro^=1;jh(nod);        if(t[nod].a[0]||t[nod].a[1])swap(t[nod].a[0],t[nod].a[1]),t[nod].ro=0;        return;    }    int mid=t[nod].lt+t[nod].rt>>1;    if(i<=mid)ro(i,j,nod*2);    if(j>mid)ro(i,j,nod*2+1);    t[nod]=t[nod*2]+t[nod*2+1];}inline int ssum(int i,int j,int nod){    pushdown(nod);    if(t[nod].lt>=i&&t[nod].rt<=j)return t[nod].sum[1];    int mid=t[nod].lt+t[nod].rt>>1,ans=0;    if(i<=mid)ans+=ssum(i,j,nod*2);    if(j>mid)ans+=ssum(i,j,nod*2+1);    return ans;}inline tree slong(int i,int j,int nod){    pushdown(nod);    if(t[nod].lt>=i&&t[nod].rt<=j)return t[nod];    int mid=t[nod].lt+t[nod].rt>>1;    if(j<=mid)return slong(i,j,nod*2);    else if(i>mid)return slong(i,j,nod*2+1);    else{        tree X=slong(i,mid,nod*2),Y=slong(mid+1,j,nod*2+1);        return X+Y;    }}int main(){    ios::sync_with_stdio(0);    cin>>n>>m;    for(int i=1;i<=n;i++)cin>>a[i];    build(1,n,1);    for(int i=1;i<=m;i++){        int l,r,z;cin>>z>>l>>r;l++;r++;        if(z<2)xg(l,r,z,1);        if(z==2)ro(l,r,1);        if(z==3)cout<<ssum(l,r,1)<<endl;        if(z==4){            tree p=slong(l,r,1);cout<<p.ss[1]<<endl;        }    }    return 0;}