只過了 HAck 秋條

P2572 [SCOI2010] 序列操作

kind_aunt @ 2024-11-20 11:12:21

#include<bits/stdc++.h>
#define int long long 
using namespace std;
const int N=1e5+5;
int n,m;
int op,l,r;
int a[N];
int tree[N<<2];
int tag1[N<<2],tag2[N<<2];
int max1[N<<2],l1[N<<2],r1[N<<2];
int max0[N<<2],l0[N<<2],r0[N<<2];
int ls(int x){return x<<1;}
int rs(int x){return x<<1|1;}
struct Tree
{
    int max1,l1,r1;
    int max0,l0,r0;
    int tree;
};
void push_up(int s,int t,int p)
{
    int mid=s+((t-s)>>1);
    tree[p]=tree[ls(p)]+tree[rs(p)];
    max1[p]=max(r1[ls(p)]+l1[rs(p)],max(max1[ls(p)],max1[rs(p)]));
    max0[p]=max(r0[ls(p)]+l0[rs(p)],max(max0[ls(p)],max0[rs(p)]));
    l1[p]=l1[ls(p)];
    r1[p]=r1[rs(p)];
    l0[p]=l0[ls(p)];
    r0[p]=r0[rs(p)];
    int lenl=mid-s+1,lenr=t-mid;
    if(lenl==tree[ls(p)]) l1[p]+=l1[rs(p)];
    if(tree[ls(p)]==0) l0[p]+=l0[rs(p)];
    if(lenr==tree[rs(p)]) r1[p]+=r1[ls(p)];
    if(tree[rs(p)]==0) r0[p]+=r0[ls(p)];
}
void build(int s,int t,int p)
{
    tag1[p]=-1;
    if(s==t)
    {
        tree[p]=max1[p]=l1[p]=r1[p]=a[s];
        max0[p]=l0[p]=r0[p]=!a[s];
        return;
    }
    int mid=s+((t-s)>>1);
    build(s,mid,ls(p));
    build(mid+1,t,rs(p));
    push_up(s,t,p);
}
void push_down(int s,int t,int p)
{
    int mid=s+((t-s)>>1);
    if(tag2[p])
    {
        tree[ls(p)]=mid-s+1-tree[ls(p)];
        tree[rs(p)]=t-mid-tree[rs(p)];
        swap(max1[ls(p)],max0[ls(p)]);
        swap(max1[rs(p)],max0[rs(p)]);
        swap(l1[ls(p)],l0[ls(p)]);
        swap(l1[rs(p)],l0[rs(p)]);
        swap(r1[ls(p)],r0[ls(p)]);
        swap(r1[rs(p)],r0[rs(p)]);
        tag2[ls(p)]=tag2[rs(p)]=1;
        tag2[p]=0;
    }
    if(tag1[p]!=-1)
    {
        if(tag1[p])
        {
            tree[ls(p)]=max1[ls(p)]=l1[ls(p)]=r1[ls(p)]=mid-s+1;
            tree[rs(p)]=max1[rs(p)]=l1[rs(p)]=r1[rs(p)]=t-mid;
            max0[ls(p)]=l0[ls(p)]=r0[ls(p)]=max0[rs(p)]=l0[rs(p)]=r0[rs(p)]=0;
            tag1[ls(p)]=tag1[rs(p)]=1;
            tag1[p]=-1;
        }
        else
        {
            tree[ls(p)]=tree[rs(p)]=max1[ls(p)]=max1[rs(p)]=l1[ls(p)]=l1[rs(p)]=r1[ls(p)]=r1[rs(p)]=0;
            max0[ls(p)]=l0[ls(p)]=r0[ls(p)]=mid-s+1;
            max0[rs(p)]=l0[rs(p)]=r0[rs(p)]=t-mid;
            tag1[ls(p)]=tag1[rs(p)]=0;
            tag1[p]=-1;
        }
    }
}
void update(int l,int r,int k,int s,int t,int p)
{
    if(l<=s and t<=r)
    {
        tree[p]=(t-s+1)*k;
        tag1[p]=k;
        if(k)
        {
            max1[p]=l1[p]=r1[p]=t-s+1;
            max0[p]=l0[p]=r0[p]=0;
        }
        else
        {
            max1[p]=l1[p]=r1[p]=0;
            max0[p]=l0[p]=r0[p]=t-s+1;
        }
        return;
    }
    int mid=s+((t-s)>>1);
    push_down(s,t,p);
    if(l<=mid) update(l,r,k,s,mid,ls(p));
    if(mid+1<=r) update(l,r,k,mid+1,t,rs(p));
    push_up(s,t,p);
}
void change(int l,int r,int s,int t,int p)
{
    if(l<=s and t<=r)
    {
        tag1[p]=-1;
        tag2[p]=!tag2[p];
        tree[p]=t-s+1-tree[p];
        swap(max1[p],max0[p]);
        swap(l1[p],l0[p]);
        swap(r1[p],r0[p]);
        return;
    }
    int mid=s+((t-s)>>1);
    push_down(s,t,p);
    if(l<=mid) change(l,r,s,mid,ls(p));
    if(mid+1<=r) change(l,r,mid+1,t,rs(p));
    push_up(s,t,p);
}
int query(int l,int r,int s,int t,int p)
{
    if(l<=s and t<=r) return tree[p];
    int mid=s+((t-s)>>1);
    push_down(s,t,p);
    int ans=0;
    if(l<=mid) ans+=query(l,r,s,mid,ls(p));
    if(mid+1<=r) ans+=query(l,r,mid+1,t,rs(p));
    return ans;
}
Tree query1(int l,int r,int s,int t,int p)
{
    if(l<=s and t<=r) return (Tree){max1[p],l1[p],r1[p],max0[p],l0[p],r0[p],tree[p]};
    int mid=s+((t-s)>>1);
    push_down(s,t,p);
    Tree ans;
    if(l<=mid and mid+1>r) return query1(l,r,s,mid,ls(p));
    if(mid+1<=r and l>mid) return query1(l,r,mid+1,r,rs(p));
    Tree ll=query1(l,r,s,mid,ls(p)),rr=query1(l,r,mid+1,t,rs(p));
    ans.tree=ll.tree+rr.tree;
    ans.max1=max(ll.r1+rr.l1,max(ll.max1,rr.max1));
    ans.max0=max(ll.r0+rr.l0,max(ll.max0,rr.max0));
    ans.l1=ll.l1;
    ans.r1=rr.r1;
    ans.l0=ll.l0;
    ans.r0=rr.r0;
    if(mid-s+1==ll.tree) ans.l1=ll.tree+rr.l1;
    if(ll.tree==0) ans.l0=mid-s+1+rr.l0;
    if(t-mid==rr.tree) ans.r1=rr.tree+ll.r1;
    if(rr.tree==0) ans.r0=t-mid+ll.r0;
    return ans;
}
signed main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    build(1,n,1);
    while(m--)
    {
        cin>>op>>l>>r;
        ++l,++r;
        if(op<=1) update(l,r,op,1,n,1);
        else if(op==2) change(l,r,1,n,1);
        else if(op==3) cout<<query(l,r,1,n,1)<<'\n';
        else cout<<query1(l,r,1,n,1).max1<<'\n';
    }
    return 0;
}
//10 3 0 0 0 0 0 0 0 0 0 0

by kind_aunt @ 2024-11-20 11:14:43

不知道為什麼,輸入法變成繁體字了。


by bsdsdb @ 2024-11-20 11:33:47

@kind_aunt Ctrl+Shift+F


by Harumaki_Gohan @ 2024-11-20 11:45:21

還真這樣


by Harumaki_Gohan @ 2024-11-20 11:49:57

但是你這個query的寫法有點屎山了,建議改一下


by bsdsdb @ 2024-11-20 12:03:35

@kind_aunt 先把區間信息重構成結構體寫法吧


|