線段樹——BZOJ1858/Luogu2572 [SCOI2010]序列操作

題面: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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章