分块0tps求调

P2572 [SCOI2010] 序列操作

JoyLosingK @ 2024-10-06 20:40:07

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e5+5,sqN=320;
int n,m,a[N],s[sqN],key;
int tagst[sqN],tagnd[sqN],by[sqN],pos[N],lm[sqN],rm[sqN];
int op,ql,qr;
inline int read(){
    int x=0,f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
    return x*f;}
inline int sum(int l,int r){ int res=0;
    if(tagst[pos[r]]) return 0;
    if(tagnd[pos[r]]) return r-l+1;
    for(int i=l;i<=r;i++) res+=by[pos[r]]?(~a[i]):a[i];
    return res;}
inline void push_down(int y){
    if(tagst[y]) for(int i=lm[y];i<=rm[y];i++) a[i]=0;
    if(tagnd[y]) for(int i=lm[y];i<=rm[y];i++) a[i]=1;
    if(by[y]) for(int i=lm[y];i<=rm[y];i++) a[i]=!a[i];
    tagst[y]=tagnd[y]=by[y]=0;}
inline int query(int l,int r){
    int ls=pos[l],rs=pos[r],res=0;
    if(ls==rs){return sum(l,r);}
    res+=sum(l,rm[ls]),res+=sum(lm[rs],r);
    for(int i=ls+1;i<=rs-1;i++)
        if(tagst[i]) continue;
    else if(tagnd[i]) res+=r-l+1;
    else if(by[i]) res+=key-s[i];
    else res+=s[i];
    return res;}
inline void upt_one(int l,int r){
    int ls=pos[l],rs=pos[r];
    if(ls==rs){ push_down(rs);
        for(int i=l;i<=r;i++) if(a[i]) a[i]=0,s[i]--;
        return;} push_down(ls),push_down(rs);
    for(int i=l;i<=rm[ls];i++) if(a[i]) a[i]=0,s[i]--;
    for(int i=lm[rs];i<=r;i++) a[i]=0;
    for(int i=ls+1;i<=rs-1;i++) tagnd[i]=by[i]=0,tagst[i]=1,s[i]=0;
    return;}
inline void upt_two(int l,int r){
    int ls=pos[l],rs=pos[r];
    if(ls==rs){ push_down(rs);
        for(int i=l;i<=r;i++) if(!a[i]) a[i]=1,s[i]++;
        return;} push_down(ls),push_down(rs);
    for(int i=l;i<=rm[ls];i++) if(!a[i]) a[i]=1,s[i]++;
    for(int i=lm[rs];i<=r;i++) if(!a[i]) a[i]=1,s[i]++;
    for(int i=ls+1;i<=rs-1;i++) tagst[i]=by[i]=0,tagnd[i]=1;
    return;}
inline void upt_three(int l,int r){
    int ls=pos[l],rs=pos[r];
    if(ls==rs){ push_down(rs);
        for(int i=l;i<=r;i++) if(!a[i]) a[i]=1,s[i]++;
        else a[i]=0,s[i]--;
        return;} push_down(ls),push_down(rs);
    for(int i=l;i<=rm[ls];i++) if(!a[i]) a[i]=1,s[i]++;
    else a[i]=0,s[i]--;
    for(int i=lm[rs];i<=r;i++) if(!a[i]) a[i]=1,s[i]++;
    else a[i]=0,s[i]--;
    for(int i=ls+1;i<=rs-1;i++)
        if(tagst[i]) tagst[i]=0,tagnd[i]=1;
    else if(tagnd[i]) tagst[i]=0,tagnd[i]=1;
    else by[i]=1;
    return;}
inline int getans(int l,int r){ int ans=0,res=0;
    for(int i=l;i<=r;i++)
        if(a[i]) ans++,res=max(ans,res); else ans=0;
    return res;}
int main(){ n=read(),m=read(),key=sqrt(n);
    for(int i=1;i<=n;i++)
        a[i]=read(),pos[i]=i/key+1,s[pos[i]]+=a[i];
    for(int i=1;i<=pos[n];i++)
        lm[i]=rm[i-1]+1,rm[i]=min(n,i*key);
    while(m--){ op=read(),ql=read(),qr=read();
        if(!op) upt_one(ql,qr);
        else if(op==1) upt_two(ql,qr);
        else if(op==2) upt_three(ql,qr);
        else if(op==3) cout<<query(ql,qr)<<endl;
        else cout<<getans(ql,qr)<<endl;
    } return 0;
}

|