社区讨论

样例过了,hack过了,剩下的WA 0pts求条

P2572[SCOI2010] 序列操作参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mmdfzuph
此快照首次捕获于
2026/03/05 20:29
5 天前
此快照最后确认于
2026/03/07 19:15
3 天前
查看原帖

rt

样例正确,hack也是对的,但是主测试点都是WA,找AI问了半天,结果AI都一直在注意细节部分,改了很久都没效果,进食后人也看了,似乎对我没帮助,这才来麻烦各位DL的 (qwq)
CPP
c++
#include<bits/stdc++.h>
#define maxn 100086
using namespace std;

struct node{
    int sum,len;
    int l0,l1,r0,r1,m0,m1;
    signed char ch;
    bool re;
    node(){
        l0=l1=r0=r1=m0=m1=sum=len=0;
        ch=-1;
        re=0;
    }
};
vector<bool>a(maxn);
vector<node>t(maxn<<2);

void push_up(int p){
    node&t1=t[p<<1],&t2=t[p<<1|1];
    t[p].sum=t1.sum+t2.sum;
    t[p].l0=(t1.l0==t1.len?t1.l0+t2.l0:t1.l0);
    t[p].l1=(t1.l1==t1.len?t1.l1+t2.l1:t1.l1);
    t[p].r0=(t2.r0==t2.len?t2.r0+t1.r0:t2.r0);
    t[p].r1=(t2.r1==t2.len?t2.r1+t1.r1:t2.r1);
    t[p].m0=max({t[p].l0,t[p].r0,t1.m0,t2.m0,t1.r0+t2.l0});
    t[p].m1=max({t[p].l1,t[p].r1,t1.m1,t2.m1,t1.r1+t2.l1});
}

void push_down(int p){
    if(t[p].len==1){
        t[p].ch=-1;
        t[p].re=0;
        return;
    }
    if(t[p].ch==-1&&t[p].re==0)return;
    node&t1=t[p<<1],&t2=t[p<<1|1];
    if(t[p].ch!=-1){
        t1.ch=t2.ch=t[p].ch;
        t1.re=t2.re=0;
    }
    if(t1.ch!=-1)
        t1.ch^=t[p].re;
    else
        t1.re^=t[p].re;
    if(t2.ch!=-1)
        t2.ch^=t[p].re;
    else
        t2.re^=t[p].re;
    auto apply=[](node&tp){
        if(tp.ch==0){
            tp.l0=tp.r0=tp.m0=tp.len;
            tp.l1=tp.r1=tp.m1=tp.sum=0;
        }
        if(tp.ch==1){
            tp.l0=tp.r0=tp.m0=0;
            tp.l1=tp.r1=tp.m1=tp.sum=tp.len;
        }
        if(tp.re){
            swap(tp.l0,tp.l1);
            swap(tp.r0,tp.r1);
            swap(tp.m0,tp.m1);
            tp.sum=tp.len-tp.sum;
        }
        tp.re=0;
    };
    apply(t1);
    apply(t2);
    t[p].ch=-1;
    t[p].re=0;
}

void build(int p,int l,int r){
    if(l==r){
        t[p].sum=t[p].l1=t[p].r1=t[p].m1=a[l];
        t[p].l0=t[p].r0=t[p].m0=!a[l];
        t[p].len=1;
        return;
    }
    int m=(l+r)>>1;
    build(p<<1,l,m);
    build(p<<1|1,m+1,r);
    t[p].len=t[p<<1].len+t[p<<1|1].len;
    push_up(p);
}

int query_sum(int p,int l,int r,int cl,int cr){
    if(cl<=l&&cr>=r)return t[p].sum;
    int m=(l+r)>>1,ans=0;
    push_down(p);
    if(cl<=m)
        ans+=query_sum(p<<1,l,m,cl,cr);
    if(cr>m)
        ans+=query_sum(p<<1|1,m+1,r,cl,cr);
    return ans;
}

array<int,4>query_string(int p,int l,int r,int cl,int cr){
    if(cl<=l&&cr>=r)return{t[p].m1,t[p].l1,t[p].r1,t[p].len};
    int m=(l+r)>>1;
    array<int,4>a1={},a2={},ans={};
    bool sign=0;
    push_down(p);
    if(cl<=m){
        a1=query_string(p<<1,l,m,cl,cr);
        sign=1;
    }
    if(cr>m){
        a2=query_string(p<<1|1,m+1,r,cl,cr);
        if(sign){
            ans[0]=max({a1[0],a2[0],a1[2]+a2[1]});
            ans[1]=(a1[1]==a1[3]?a1[1]+a2[1]:a1[1]);
            ans[2]=(a2[2]==a2[3]?a2[2]+a1[2]:a2[2]);
            ans[3]=a1[3]+a2[3];
        }else{
            ans[0]=a2[0];
            ans[1]=a2[1];
            ans[2]=a2[2];
            ans[3]=a2[3];
        }
        sign=0;
    }
    if(sign){
        ans[0]=a1[0];
        ans[1]=a1[1];
        ans[2]=a1[2];
        ans[3]=a1[3];
    }
    return ans;
}

void change(int p,bool s,int l,int r,int cl,int cr){
    if(cl<=l&&cr>=r){
        if(s){
            t[p].l0=t[p].r0=t[p].m0=0;
            t[p].l1=t[p].r1=t[p].m1=t[p].sum=t[p].len;
        }else{
            t[p].l0=t[p].r0=t[p].m0=t[p].len;
            t[p].l1=t[p].r1=t[p].m1=t[p].sum=0;
        }
        t[p].ch=s;
        t[p].re=0;
        return;
    }
    int m=(l+r)>>1;
    push_down(p);
    if(cl<=m)
        change(p<<1,s,l,m,cl,cr);
    if(cr>m)
        change(p<<1|1,s,m+1,r,cl,cr);
    push_up(p);
}

void reverse(int p,int l,int r,int cl,int cr){
    if(cl<=l&&cr>=r){
        swap(t[p].l0,t[p].l1);
        swap(t[p].r0,t[p].r1);
        swap(t[p].m0,t[p].m1);
        t[p].sum=t[p].len-t[p].sum;
        t[p].re=!t[p].re;
        return;
    }
    int m=(l+r)>>1;
    push_down(p);
    if(cl<=m)
        reverse(p<<1,l,m,cl,cr);
    if(cr>m)
        reverse(p<<1|1,m+1,r,cl,cr);
    push_up(p);
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int n,m,i,j,l,r;
    cin>>n>>m;
    for(i=1;i<=n;i++){
        cin>>j;
        a[i]=j;
    }
    build(1,1,n);
    for(i=1;i<=m;i++){
        cin>>j>>l>>r;
        l++;r++;
        if(j<=1)
            change(1,j,1,n,l,r);
        else if(j==2)
            reverse(1,1,n,l,r);
        else if(j==3)
            cout<<query_sum(1,1,n,l,r)<<'\n';
        else if(j==4)
            cout<<query_string(1,1,n,l,r)[0]<<'\n';
    }
    return 0;
}
没注释解释一下,lenlen 表示区间长度,sumsum 表示区间内1的数量,一个 nodenode 中,m0,m1m0,m1 表示整段区间内最长的连续01串,l0,l1l0,l1 表示区间左侧连续01串长度,r0,r1r0,r1 表示区间右侧连续01串长度。
谢谢!

回复

1 条回复,欢迎继续交流。

正在加载回复...