0pts求调
查看原帖
0pts求调
1263684
Elysialr楼主2024/11/24 21:30
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define x_lc (x<<1)
#define x_rc (x<<1|1)
#define x_mid ((t[x].l+t[x].r)>>1)
#define leng(x) (t[x].r-t[x].l+1)

inline ll read(){
	ll x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x*10+ch-48);ch=getchar();}
	return x*f;
}

struct node{
    ll l,r;
    ll p,q;
    ll sum,cnt;
    bool tag[3];
    void zero(){
        tag[0]=1;
        tag[1]=0;
        tag[2]=0;
        sum=0;
    }
    void one(){
        tag[0]=0;
        tag[1]=1;
        tag[2]=0;
        sum=r-l+1;
    }
    void roll(){
        tag[2]^=1;
        sum=r-l+1-sum;
    }
};
struct SegmentTree{
    bool a[1000001];
    node t[4000001];

    void Update(ll x){
        t[x].sum=t[x_lc].sum+t[x_rc].sum;
        t[x].cnt=max(t[x_lc].cnt,t[x_rc].cnt);
        t[x].cnt=max(t[x].cnt,t[x_lc].q+t[x_rc].p);
        if(t[x_lc].sum==leng(x_lc)) t[x].p=t[x_lc].sum+t[x_rc].p;
        else t[x].p=t[x_lc].p;
        if(t[x_rc].sum==leng(x_rc)) t[x].q=t[x_rc].sum+t[x_lc].q;
        else t[x].q=t[x_rc].p;
    }
    void PushDown(ll x){
        if(t[x].tag[1]){
            t[x].tag[1]=0;
            t[x_lc].one();
            t[x_rc].one();
        }
        if(t[x].tag[0]){
            t[x].tag[0]=0;
            t[x_lc].zero();
            t[x_rc].zero();
        }
        if(t[x].tag[2]){
            t[x].tag[2]=0;
            t[x_lc].roll();
            t[x_rc].roll();
        }
    }
    
    void Build(ll x,ll l,ll r){
        t[x].l=l;
        t[x].r=r;
        t[x].tag[0]=0;
        t[x].tag[1]=0;
        t[x].tag[2]=0;
        if(l==r){
            if(a[l]) t[x].sum=t[x].cnt=t[x].p=t[x].q=1;
            else t[x].sum=t[x].cnt=t[x].p=t[x].q=0;
            return;
        }
        Build(x_lc,l,x_mid);
        Build(x_rc,x_mid+1,r);
        Update(x);
    }
    void Zero(ll x,ll l,ll r){
        if(t[x].l>=l&&t[x].r<=r){
            t[x].sum=0;
            t[x].tag[0]=1;
            t[x].tag[1]=0;
            t[x].tag[2]=0;
            return;
        }
        PushDown(x);
        if(x_mid>=l) Zero(x_lc,l,r);
        if(x_mid+1<=r) Zero(x_rc,l,r);
        Update(x);
    }
    void One(ll x,ll l,ll r){
        if(t[x].l>=l&&t[x].r<=r){
            t[x].sum=leng(x);
            t[x].tag[0]=0;
            t[x].tag[1]=1;
            t[x].tag[2]=0;
            return;
        }
        PushDown(x);
        if(x_mid>=l) One(x_lc,l,r);
        if(x_mid+1<=r) One(x_rc,l,r);
        Update(x);
    }
    void Xor(ll x,ll l,ll r){
        PushDown(x);
        if(t[x].l>=l&&t[x].r<=r){
            t[x].sum=leng(x)-t[x].sum;
            t[x].tag[2]^=1;
            return;
        }
        if(x_mid>=l) Xor(x_lc,l,r);
        if(x_mid+1<=r) Xor(x_rc,l,r);
        Update(x);
    }

    ll GetSum(ll x,ll l,ll r){
        if(t[x].l>=l&&t[x].r<=r) return t[x].sum;
        ll res=0;
        PushDown(x);
        if(x_mid>=l) res+=GetSum(x_lc,l,r);
        if(x_mid+1<=r) res+=GetSum(x_rc,l,r);
        return res;
    }
    node GetCnt(ll x,ll l,ll r){
        if(t[x].l>=l&&t[x].r<=r) return t[x];
        PushDown(x);
        if(x_mid>=l&&x_mid+1<=r){
            node lc=GetCnt(x_lc,l,r);
            node rc=GetCnt(x_rc,l,r);
            node res;
            res.l=lc.l;
            res.r=rc.r;
            res.sum=lc.sum+rc.sum;
            res.cnt=max(lc.cnt,rc.cnt);
            res.cnt=max(res.cnt,lc.q+rc.p);
            if(lc.sum==lc.r-lc.l+1) res.p=lc.sum+rc.p;
            else res.p=lc.p;
            if(rc.sum==rc.r-rc.l+1) res.q=rc.sum+lc.q;
            else res.q=rc.p;
            return res;
        }
        if(x_mid>=l&&x_mid+1>r) return GetCnt(x_lc,l,r);
        if(x_mid+1<=r&&x_mid<l) return GetCnt(x_rc,l,r);
    }

    void init(ll n){
        for(ll i=1;i<=n;i++)
        cin>>a[i];
        Build(1,1,n);
    }
    void solve(ll m){
        for(ll i=1;i<=m;i++){
            ll op=read();
            ll l=read()+1;
            ll r=read()+1;
            if(op==0) Zero(1,l,r);
            if(op==1) One(1,l,r);
            if(op==2) Xor(1,l,r);
            if(op==3) cout<<GetSum(1,l,r)<<endl;
            if(op==4) cout<<GetCnt(1,l,r).cnt<<endl;
        }
    }
};

SegmentTree SGT;

int main(){
    ll n,m;
    cin>>n>>m;
    SGT.init(n);
    SGT.solve(m);
    return 0;
}
2024/11/24 21:30
加载中...