HDU 3397 線段樹 雙懶惰標記

來源:互聯網
上載者:User

標籤:blog   os   io   for   re   問題   

這個是去年遺留曆史問題,之前思路混亂,搞了好多發都是WA,就沒做了

自從上次做了大白書上那個雙重懶惰標記的題目,做這個就思路很清晰了

跟上次大白上那個差不多,這個也是有一個sets標記,代表這個區間全部置為0或者1,沒有置位的時候為-1

還有個rev標記,代表翻轉操作,0代表當前不翻,1代表當前翻

要注意一下優先順序,發現有不同的弄法,我是這個弄得,有set操作的時候,set標記設值,並把當前節點的rev標記設為0,因為不管要不要rev,當前set操作肯定直接覆蓋了

rev操作不改變set操作,在pushdown的時候,先考慮set標記再弄rev標記,這也是很好理解的,因為一旦rev和set共存,肯定是rev在set後面。

有幾個細節要注意一下,一開始行雲流水一氣呵成,發現還是WA了,就是這幾個地方,

1.除了set的時候強制給rev弄成0,其他任何時候對rev標記操作都是^1,取反,這個也很好理解,之前在pushdown裡面我就是直接傳值,肯定不對嘛

2.在pushdown裡面的set下傳操作也要記得把子樹的rev標記抹除,一開始只在主修改函數裡寫了,這裡沒寫,WA的不明不白,理由跟上面的一樣

然後就基本上沒問題了

#include <iostream>#include <cstdio>#include <cstring>#define lson rt<<1,l,mid#define rson rt<<1|1,mid+1,rusing namespace std;const int N=100000+10;int d[N*3],maxc[N*3],lc[N*3],rc[N*3],maxc0[N*3],lc0[N*3],rc0[N*3];int sets[N*3],rev[N*3];int n,Q;int A[N];void up(int rt,int l,int r){    int mid=(l+r)>>1;    d[rt]=d[rt<<1]+d[rt<<1|1];    maxc[rt]=max(maxc[rt<<1],maxc[rt<<1|1]);    maxc[rt]=max(maxc[rt],lc[rt<<1|1]+rc[rt<<1]);    lc[rt]=lc[rt<<1];    rc[rt]=rc[rt<<1|1];    if (lc[rt<<1]==mid-l+1) lc[rt]+=lc[rt<<1|1];    if (rc[rt<<1|1]==r-mid) rc[rt]+=rc[rt<<1];    maxc0[rt]=max(maxc0[rt<<1],maxc0[rt<<1|1]);    maxc0[rt]=max(maxc0[rt],lc0[rt<<1|1]+rc0[rt<<1]);    lc0[rt]=lc0[rt<<1];    rc0[rt]=rc0[rt<<1|1];    if (lc0[rt<<1]==mid-l+1) lc0[rt]+=lc0[rt<<1|1];    if (rc0[rt<<1|1]==r-mid) rc0[rt]+=rc0[rt<<1];}void build(int rt,int l,int r){    sets[rt]=-1;    rev[rt]=0;    if (l>=r){        d[rt]=maxc[rt]=A[l];        lc[rt]=rc[rt]=A[l];        lc0[rt]=rc0[rt]=maxc0[rt]=1-A[l];        return;    }    int mid=(l+r)>>1;    build(lson);    build(rson);    up(rt,l,r);}void pushdown(int rt,int l,int r){    if (l>=r) return;    int mid=(l+r)>>1;    if (sets[rt]>=0){        maxc[rt<<1]=lc[rt<<1]=rc[rt<<1]=d[rt<<1]=(mid-l+1)*sets[rt];        maxc[rt<<1|1]=lc[rt<<1|1]=rc[rt<<1|1]=d[rt<<1|1]=(r-mid)*sets[rt];        maxc0[rt<<1]=lc0[rt<<1]=rc0[rt<<1]=(mid-l+1)*(1-sets[rt]);        maxc0[rt<<1|1]=lc0[rt<<1|1]=rc0[rt<<1|1]=(r-mid)*(1-sets[rt]);        sets[rt<<1]=sets[rt<<1|1]=sets[rt];        rev[rt<<1]=rev[rt<<1|1]=0;        sets[rt]=-1;    }    if (rev[rt]>0){        d[rt<<1]=(mid-l+1)-d[rt<<1];        d[rt<<1|1]=(r-mid)-d[rt<<1|1];        int t1,t2,t3;        t1=maxc[rt<<1];t2=lc[rt<<1];t3=rc[rt<<1];        maxc[rt<<1]=maxc0[rt<<1];        lc[rt<<1]=lc0[rt<<1];        rc[rt<<1]=rc0[rt<<1];        maxc0[rt<<1]=t1;        lc0[rt<<1]=t2;        rc0[rt<<1]=t3;        t1=maxc[rt<<1|1];t2=lc[rt<<1|1];t3=rc[rt<<1|1];        maxc[rt<<1|1]=maxc0[rt<<1|1];        lc[rt<<1|1]=lc0[rt<<1|1];        rc[rt<<1|1]=rc0[rt<<1|1];        maxc0[rt<<1|1]=t1;        lc0[rt<<1|1]=t2;        rc0[rt<<1|1]=t3;        rev[rt<<1]^=1;        rev[rt<<1|1]^=1;        rev[rt]=0;    }}void change(int val,int L,int R,int rt,int l,int r){    if (L<=l && r<=R){        d[rt]=(r-l+1)*val;        lc[rt]=rc[rt]=(r-l+1)*val;        maxc[rt]=(r-l+1)*val;        lc0[rt]=rc0[rt]=maxc0[rt]=(r-l+1)*(1-val);        sets[rt]=val;        rev[rt]=0;        return;    }    pushdown(rt,l,r);    int mid=(l+r)>>1;    if (L>mid) change(val,L,R,rson);    else    if (R<=mid) change(val,L,R,lson);    else{        change(val,L,R,rson);        change(val,L,R,lson);    }    up(rt,l,r);}void revers(int L,int R,int rt,int l,int r){    if (L<=l && r<=R)    {        d[rt]=(r-l+1)-d[rt];        int t1,t2,t3;        t1=maxc[rt];t2=lc[rt];t3=rc[rt];        maxc[rt]=maxc0[rt];lc[rt]=lc0[rt];rc[rt]=rc0[rt];        maxc0[rt]=t1;lc0[rt]=t2;rc0[rt]=t3;        rev[rt]^=1;        return;    }    pushdown(rt,l,r);    int mid=(l+r)>>1;    if (R<=mid) revers(L,R,lson);    else    if (L>mid) revers(L,R,rson);    else    {        revers(L,R,lson);        revers(L,R,rson);    }    up(rt,l,r);}int output(int op,int L,int R,int rt,int l,int r){    if (L==l && r==R){        if (op==3) return d[rt];        else  return maxc[rt];    }    pushdown(rt,l,r);    int mid=(l+r)>>1;    if (L>mid) return output(op,L,R,rson);    else    if (R<=mid) return output(op,L,R,lson);    else    {        int ret1=output(op,L,mid,lson);        int ret2=output(op,mid+1,R,rson);        if (op==3) return ret1+ret2;        else{            int ret=max(ret1,ret2);            int t1=min(rc[rt<<1],mid-L+1);            int t2=min(lc[rt<<1|1],R-mid);            ret=max(ret,t1+t2);            return ret;        }    }}int main(){    int t,op,a,b;    scanf("%d",&t);    while (t--)    {        scanf("%d%d",&n,&Q);        for (int i=1;i<=n;i++) scanf("%d",&A[i]);        build(1,1,n);        while (Q--)        {            scanf("%d%d%d",&op,&a,&b);            a++;b++;            if (op<=1){                change(op,a,b,1,1,n);            }            else            if (op==2){                revers(a,b,1,1,n);            }            else            {                int ans=output(op,a,b,1,1,n);                printf("%d\n",ans);            }        }    }    return 0;}

  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.