关于暴力过了。

P2572 [SCOI2010] 序列操作

CQ_Bob @ 2024-03-12 16:53:31

这题我区间覆盖写挂了。然后把区间覆盖的代码变成了暴力单点修改,结果过了……

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define re register
#define il inline
#define pii pair<int,int>
#define x first
#define y second
#define gc getchar()
#define rd read()
#define debug() puts("------------")

namespace yzqwq{
    il int read(){
        int x=0,f=1;char ch=gc;
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=gc;}
        while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^48),ch=gc;
        return x*f;
    }
    il int qmi(int a,int b,int p){
        int ans=1;
        while(b){
            if(b&1) ans=ans*a%p;
            a=a*a%p,b>>=1;
        }
        return ans;
    }
    il auto max(auto a,auto b){return (a>b?a:b);}
    il auto min(auto a,auto b){return (a<b?a:b);}
    il int gcd(int a,int b){
        if(!b) return a;
        return gcd(b,a%b);
    }
    il int lcm(int a,int b){
        return a/gcd(a,b)*b;
    }
    il void exgcd(int a,int b,int &x,int &y){
        if(!b) return x=1,y=0,void(0);
        exgcd(b,a%b,x,y);
        int t=x;
        x=y,y=t-a/b*x;
        return ;
    }
    mt19937 rnd(time(0));
}
using namespace yzqwq;

const int N=2e5+10;
int n,m,a[N];
struct Tree{
    int l,r;
    int tag1,tag2;//区间覆盖,区间翻转
    int lmax0,lmax1,rmax0,rmax1;
    int mx0,mx1;
    int cnt0,cnt1; 
}tr[N<<2];

il void up(int now){
    tr[now].lmax0=tr[now<<1].lmax0;
    if(tr[now<<1].lmax0==(tr[now<<1].r-tr[now<<1].l+1)) tr[now].lmax0+=tr[now<<1|1].lmax0;
    tr[now].lmax1=tr[now<<1].lmax1;
    if(tr[now<<1].lmax1==(tr[now<<1].r-tr[now<<1].l+1)) tr[now].lmax1+=tr[now<<1|1].lmax1;

    tr[now].rmax0=tr[now<<1|1].rmax0;
    if(tr[now<<1|1].rmax0==(tr[now<<1|1].r-tr[now<<1|1].l+1)) tr[now].rmax0+=tr[now<<1].rmax0;
    tr[now].rmax1=tr[now<<1|1].rmax1;
    if(tr[now<<1|1].rmax1==(tr[now<<1|1].r-tr[now<<1|1].l+1)) tr[now].rmax1+=tr[now<<1].rmax1;

    tr[now].mx0=max(tr[now<<1].mx0,tr[now<<1|1].mx0);
    tr[now].mx0=max(tr[now].mx0,tr[now<<1].rmax0+tr[now<<1|1].lmax0);
    tr[now].mx0=max({tr[now].mx0,tr[now].lmax0,tr[now].rmax0});

    tr[now].mx1=max(tr[now<<1].mx1,tr[now<<1|1].mx1);
    tr[now].mx1=max(tr[now].mx1,tr[now<<1].rmax1+tr[now<<1|1].lmax1);
    tr[now].mx1=max({tr[now].mx1,tr[now].lmax1,tr[now].rmax1});

    tr[now].cnt0=tr[now<<1].cnt0+tr[now<<1|1].cnt0;
    tr[now].cnt1=tr[now<<1].cnt1+tr[now<<1|1].cnt1;

    return ;
}
il void down(int now){
    if(tr[now].tag1!=-1){//有区间覆盖
        tr[now<<1].tag2=tr[now<<1|1].tag2=0;
        tr[now<<1].tag1=tr[now<<1|1].tag1=tr[now].tag1;
        tr[now<<1].lmax0=tr[now<<1].lmax1=tr[now<<1|1].lmax0=tr[now<<1|1].lmax1=0;
        tr[now<<1].rmax0=tr[now<<1].rmax1=tr[now<<1|1].rmax0=tr[now<<1|1].rmax1=0;
        tr[now<<1].mx0=tr[now<<1|1].mx0=0;
        tr[now<<1].mx1=tr[now<<1|1].mx1=0;
        tr[now<<1].cnt0=tr[now<<1|1].cnt0=0;
        tr[now<<1].cnt1=tr[now<<1|1].cnt1=0;

        if(tr[now].tag1==0){
            tr[now<<1].cnt0=tr[now<<1].mx0=tr[now<<1].lmax0=tr[now<<1].rmax0=(tr[now<<1].r-tr[now<<1].l+1);
            tr[now<<1|1].cnt0=tr[now<<1|1].mx0=tr[now<<1|1].lmax0=tr[now<<1|1].rmax0=(tr[now<<1|1].r-tr[now<<1|1].l+1);
        }
        else if(tr[now].tag1==1){
            tr[now<<1].cnt1=tr[now<<1].mx1=tr[now<<1].lmax1=tr[now<<1].rmax1=(tr[now<<1].r-tr[now<<1].l+1);
            tr[now<<1|1].cnt1=tr[now<<1|1].mx1=tr[now<<1|1].lmax1=tr[now<<1|1].rmax1=(tr[now<<1|1].r-tr[now<<1|1].l+1);
        }
        tr[now].tag1=-1;
    }
    if(tr[now].tag2!=0){//有区间翻转
        if(tr[now<<1].tag1!=-1) tr[now<<1].tag1^=1;
        if(tr[now<<1|1].tag1!=-1) tr[now<<1|1].tag1^=1;
        tr[now<<1].tag2^=1,tr[now<<1|1].tag2^=1;

        swap(tr[now<<1].cnt0,tr[now<<1].cnt1),
        swap(tr[now<<1].lmax0,tr[now<<1].lmax1),
        swap(tr[now<<1].rmax0,tr[now<<1].rmax1),
        swap(tr[now<<1].mx0,tr[now<<1].mx1);

        swap(tr[now<<1|1].cnt0,tr[now<<1|1].cnt1),
        swap(tr[now<<1|1].lmax0,tr[now<<1|1].lmax1),
        swap(tr[now<<1|1].rmax0,tr[now<<1|1].rmax1),
        swap(tr[now<<1|1].mx0,tr[now<<1|1].mx1);

        tr[now].tag2=0;  
    }
    return ;
}
il void build(int now,int l,int r){
    tr[now].l=l,tr[now].r=r,tr[now].tag1=-1,tr[now].tag2=0;
    if(l==r){
        if(a[l]==0) tr[now].cnt0=tr[now].lmax0=tr[now].rmax0=tr[now].mx0=1;
        if(a[l]==1) tr[now].cnt1=tr[now].lmax1=tr[now].rmax1=tr[now].mx1=1;
        return ;
    }
    int mid=l+r>>1;
    build(now<<1,l,mid),build(now<<1|1,mid+1,r);
    return up(now),void(0);
}
il void insert1(int now,int l,int r,int k){//区间覆盖 
//  if(tr[now].l>=l&&tr[now].r<=r){
    if(tr[now].l==tr[now].r){
        tr[now].cnt0=tr[now].cnt1=0;
        tr[now].lmax0=tr[now].lmax1=0;
        tr[now].mx0=tr[now].mx1=0;
        tr[now].rmax0=tr[now].rmax1=0;
        tr[now].tag2=0,tr[now].tag1=k;
        if(k==0) tr[now].cnt0=tr[now].lmax0=tr[now].rmax0=tr[now].mx0=tr[now].r-tr[now].l+1;
        if(k==1) tr[now].cnt1=tr[now].lmax1=tr[now].rmax1=tr[now].mx1=tr[now].r-tr[now].l+1;
        return ;
    }
    down(now);
    int mid=tr[now].l+tr[now].r>>1;
    if(l<=mid) insert1(now<<1,l,r,k);
    if(mid<r) insert1(now<<1|1,l,r,k);
    return up(now),void(0);
}
il void insert2(int now,int l,int r){//区间翻转
    if(tr[now].l>=l&&tr[now].r<=r){
        swap(tr[now].cnt0,tr[now].cnt1);
        swap(tr[now].lmax0,tr[now].lmax1);
        swap(tr[now].mx0,tr[now].mx1);
        swap(tr[now].rmax0,tr[now].rmax1);
        tr[now].tag2^=1;
        return ;
    }
    down(now);
    int mid=tr[now].l+tr[now].r>>1;
    if(l<=mid) insert2(now<<1,l,r);
    if(mid<r) insert2(now<<1|1,l,r);
    return up(now),void(0);
}
il int query1(int now,int l,int r){//区间1的数量 
    if(tr[now].l>=l&&tr[now].r<=r) return tr[now].cnt1;
    down(now);
    int ans=0,mid=tr[now].l+tr[now].r>>1;
    if(l<=mid) ans+=query1(now<<1,l,r);
    if(mid<r) ans+=query1(now<<1|1,l,r);
    return up(now),ans;
}
il Tree query2(int now,int l,int r){//区间连续1的数量
    if(tr[now].l>=l&&tr[now].r<=r) return tr[now];
    down(now);
    Tree ans={0,0,0,0,0,0,0,0,0,0,0,0};
    int mid=tr[now].l+tr[now].r>>1;
    if(l<=mid) ans=query2(now<<1,l,r);
    if(mid<r){
        Tree ans2=query2(now<<1|1,l,r); 
        ans.mx1=max(ans.mx1,ans2.mx1);
        ans.mx1=max(ans.mx1,ans.rmax1+ans2.lmax1);
        if(ans.lmax1==mid-max(l,tr[now].l)+1) ans.lmax1+=ans2.lmax1;
        int rmax1=ans2.rmax1;
        if(rmax1==min(r,tr[now].r)-(mid+1)+1) rmax1+=ans.rmax1;
        ans.rmax1=rmax1;
        ans.mx1=max({ans.mx1,ans.lmax1,ans.rmax1});
    }
    return up(now),ans;
}

il void solve(){
    n=rd,m=rd;
    for(re int i=1;i<=n;++i) a[i]=rd;
    build(1,1,n);
    for(re int i=1;i<=m;++i){
        int op=rd,l=rd+1,r=rd+1;
        if(op==0) insert1(1,l,r,0);
        else if(op==1) insert1(1,l,r,1);
        else if(op==2) insert2(1,l,r);
        else if(op==3){
            int ans=query1(1,l,r);
            printf("%lld\n",ans);
        }
        else if(op==4){
            Tree ans=query2(1,l,r);
            printf("%lld\n",ans.mx1);
        }
//      for(re int j=1;j<=n;++j){
//          cout<<query1(1,j,j)<<" ";
//      }
//      cout<<"\n";
    }
    return ;
}

signed main(){
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    int t=1;while(t--)
    solve();
    return 0;
}
/*
10 11
0 1 0 0 1 1 1 1 0 1
3 0 9
0 0 0
0 1 3
4 1 3
4 1 5
2 1 5
4 1 5
1 5 5
4 1 5
1 4 4
4 1 5
*/

第 135 行是改的暴力。


|