10pts求助

P2572 [SCOI2010] 序列操作

FxorG @ 2020-11-28 18:17:42

// tag=1 : 0 tag =2 :1 tag=-1 null

#include <cstdio>
#include <algorithm>
#include <iostream> 
#include <cstring>

#define N (int)(1e5+20)
#define ls (cur<<1)
#define rs (ls+1)
#define mid ((l+r)>>1)

using namespace std; 

struct tree {
    int sum0,sum1,ml1,mr1,ml0,mr0,len,ans0,ans1,tag,tag2;
}t[N<<2];

int a[N];
int n,m;

void push_up(int cur) {
    t[cur].sum0=t[ls].sum0+t[rs].sum0;
    t[cur].sum1=t[ls].sum1+t[rs].sum1;

    if(t[ls].sum0==t[ls].len) t[cur].ml0=t[ls].len+t[rs].ml0;
    else t[cur].ml0=t[ls].ml0;
    if(t[rs].sum0==t[rs].len) t[cur].mr0=t[rs].len+t[ls].mr0;
    else t[cur].mr0=t[rs].mr0;
    if(t[ls].sum1==t[ls].len) t[cur].ml1=t[ls].len+t[rs].ml1;
    else t[cur].ml1=t[ls].ml1;
    if(t[rs].sum1==t[rs].len) t[cur].mr1=t[rs].len+t[ls].mr1;
    else t[cur].mr1=t[rs].mr1;

    t[cur].ans0=max(max(t[ls].ans0,t[rs].ans0),t[ls].mr0+t[rs].ml0);
    t[cur].ans1=max(max(t[ls].ans1,t[rs].ans1),t[ls].mr1+t[rs].ml1); 
}

void push_down(int cur) {
    if(t[cur].tag==1) {
        t[ls].sum0=t[ls].ml0=t[ls].mr0=t[ls].ans0=t[ls].len;
        t[ls].sum1=t[ls].ml1=t[ls].mr1=t[ls].ans1=0;
        t[ls].tag=1;
        t[rs].sum0=t[rs].ml0=t[rs].mr0=t[rs].ans0=t[rs].len;
        t[rs].sum1=t[rs].ml1=t[rs].mr1=t[rs].ans1=0;
        t[rs].tag=1;
        t[cur].tag=0;
    } else if(t[cur].tag==2) {
        t[ls].sum0=t[ls].ml0=t[ls].mr0=t[ls].ans0=0;
        t[ls].sum1=t[ls].ml1=t[ls].mr1=t[ls].ans1=t[ls].len;
        t[ls].tag=2;
        t[rs].sum0=t[rs].ml0=t[rs].mr0=t[rs].ans0=0;
        t[rs].sum1=t[rs].ml1=t[rs].mr1=t[rs].ans1=t[rs].len;
        t[rs].tag=2;
        t[cur].tag=0;
    } 
    if(t[cur].tag2) {
        swap(t[ls].sum0,t[ls].sum1);
        swap(t[ls].ml0,t[ls].ml1);
        swap(t[ls].mr0,t[ls].mr1);
        swap(t[ls].ans0,t[ls].ans1);
        swap(t[rs].sum0,t[rs].sum1);
        swap(t[rs].ml0,t[rs].ml1);
        swap(t[rs].mr0,t[rs].mr1);
        swap(t[rs].ans0,t[rs].ans1);
        t[ls].tag2^=1; t[rs].tag2^=1;
        t[cur].tag2=0;
    }
}

void build(int cur,int l,int r) {
    t[cur].tag=0;
    t[cur].tag2=0;
    t[cur].len=r-l+1;
    if(l==r) {
        t[cur].sum0=t[cur].ml0=t[cur].mr0=t[cur].ans0=a[l]==0;
        t[cur].sum1=t[cur].ml1=t[cur].mr1=t[cur].ans1=a[l]==1;
        return; 
    }
    build(ls,l,mid); build(rs,mid+1,r);
    push_up(cur);
}

void update(int cur,int l,int r,int cl,int cr,int x) {
    if(cl<=l&&r<=cr) {
        if(x==0) {
            t[cur].sum0=t[cur].ml0=t[cur].mr0=t[cur].ans0=t[cur].len;
            t[cur].sum1=t[cur].ml1=t[cur].mr1=t[cur].ans1=0;
            t[cur].tag=1; t[cur].tag2=0;
        } else if(x==1){
            t[cur].sum0=t[cur].ml0=t[cur].mr0=t[cur].ans0=0;
            t[cur].sum1=t[cur].ml1=t[cur].mr1=t[cur].ans1=t[cur].len;
            t[cur].tag=2; t[cur].tag2=0;
        } else {
            swap(t[cur].sum0,t[cur].sum1);
            swap(t[cur].ml0,t[cur].ml1);
            swap(t[cur].mr0,t[cur].mr1);
            swap(t[cur].ans0,t[cur].ans1);
            t[cur].tag2^=1;
        }
        return;
    }
    push_down(cur);
    if(cl<=mid) update(ls,l,mid,cl,cr,x);
    if(cr>mid) update(rs,mid+1,r,cl,cr,x);
    push_up(cur);
}

int query2(int cur,int l,int r,int cl,int cr) {
    if(cl<=l&&r<=cr) return t[cur].sum1;
    push_down(cur);
    int ans=0;
    if(cl<=mid) ans+=query2(ls,l,mid,cl,cr);
    if(cr>mid) ans+=query2(rs,mid+1,r,cl,cr);
    return ans;
}

tree query(int cur,int l,int r,int cl,int cr) {
    if(cl<=l&&r<=cr) return t[cur];
    push_down(cur);
    if(cr<=mid) return query(ls,l,mid,cl,cr);
    else if(cl>mid) return query(rs,mid+1,r,cl,cr);
    else {
        tree ans;
        tree lans=query(ls,l,mid,cl,cr),rans=query(rs,mid+1,r,cl,cr);
        ans.sum1=lans.sum1+rans.sum1;
        if(lans.sum1==lans.len) ans.ml1=lans.len+rans.ml1;
        else ans.ml1=lans.ml1;
        if(rans.sum1==rans.len) ans.mr1=rans.len+lans.mr1;
        else ans.mr1=rans.mr1;
        ans.ans1=max(max(lans.ans1,rans.ans1),lans.mr1+rans.ml1);
        return ans;
    }
}

int main() {
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    build(1,1,n);
    int opt,x,y;
    for(int i=1;i<=m;i++) {
        scanf("%d%d%d",&opt,&x,&y);
        ++x; ++y;
        if(opt==0) {
            update(1,1,n,x,y,0);
        } else if(opt==1) {
            update(1,1,n,x,y,1);
        } else if(opt==2) {
            update(1,1,n,x,y,2);
        } else if(opt==3) {
            printf("%d\n",query2(1,1,n,x,y));
        } else {
            printf("%d\n",query(1,1,n,x,y).ans1);
        }
    }
    return 0;
}

by guodong @ 2020-11-28 18:27:30

orz xgf

不过这种题没什么人愿意帮你调的吧..

建议学小粉兔重载合并操作,会方便不少


|