玄无限关,求条
查看原帖
玄无限关,求条
740333
Rannio楼主2024/12/19 21:54

10 pts,改 4 天了感觉要调似了救命啊啊 qwq。

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m;
struct seg{
    int l,r,lsum,rsum,lz,lz1,sum,gs;
}tree[1000005];
void upd(int now){
    tree[now].gs=tree[now<<1].gs+tree[now<<1|1].gs;
    tree[now].sum=max(tree[now<<1].sum,max(tree[now<<1|1].sum,tree[now<<1].rsum+tree[now<<1|1].lsum));
    if(tree[now<<1].lsum==tree[now<<1].r-tree[now<<1].l+1) tree[now].lsum=tree[now<<1].lsum+tree[now<<1|1].lsum;
    else tree[now].lsum=tree[now<<1].lsum;
    if(tree[now<<1|1].rsum==tree[now<<1|1].r-tree[now<<1|1].l+1) tree[now].rsum=tree[now<<1|1].rsum+tree[now<<1].rsum;
    else tree[now].rsum=tree[now<<1|1].rsum;
}
void build(int now,int l,int r){
    tree[now].l=l,tree[now].r=r;
    if(l==r){
        tree[now].lsum=tree[now].rsum=tree[now].sum=0;
        tree[now].gs=1;
        return ;
    }
    int mid=(l+r)>>1;
    build(now<<1,l,mid);
    build(now<<1|1,mid+1,r);
    upd(now);
}
void pushd(int now){
    if(tree[now].lz1){
        int mid=(tree[now].l+tree[now].r)>>1;
        tree[now<<1].gs=tree[now<<1|1].gs=0;
        tree[now<<1].sum=tree[now<<1].lsum=tree[now<<1].rsum=mid-tree[now].l+1;
        tree[now<<1|1].sum=tree[now<<1|1].lsum=tree[now<<1|1].rsum=tree[now].r-mid;
        tree[now<<1].lz1=tree[now<<1|1].lz1=1;
        tree[now].lz1=0;
    }
    if(tree[now].lz){
        int mid=(tree[now].l+tree[now].r)>>1;
        tree[now<<1].gs=mid-tree[now].l+1;
        tree[now<<1|1].gs=tree[now].r-mid;
        tree[now<<1].sum=tree[now<<1].lsum=tree[now<<1].rsum=0;
        tree[now<<1|1].sum=tree[now<<1|1].lsum=tree[now<<1|1].rsum=0;
        tree[now<<1].lz=tree[now<<1|1].lz=1;
        tree[now].lz=0;
    }
}
void change1(int now,int l,int r){//区间改0
    if(tree[now].l>=l&&tree[now].r<=r){
        tree[now].sum=tree[now].lsum=tree[now].rsum=tree[now].r-tree[now].l+1;
        tree[now].gs=0;
        tree[now].lz1=1;
        tree[now].lz=0;
        return ;
    }
    if(tree[now].lz||tree[now].lz1) pushd(now);
    if(r<=tree[now<<1].r) change1(now<<1,l,r);
    else if(l>=tree[now<<1|1].l) change1(now<<1|1,l,r);
    else change1(now<<1,l,tree[now<<1].r),change1(now<<1|1,tree[now<<1|1].l,r);
    upd(now);
}
void change2(int now,int l,int r){//区间改1
    if(tree[now].l>=l&&tree[now].r<=r){
        tree[now].sum=0;
        tree[now].lsum=0;
        tree[now].rsum=0;
        tree[now].gs=tree[now].r-tree[now].l+1;
        tree[now].lz=1;
        tree[now].lz1=0;
        return ;
    }
    if(tree[now].lz||tree[now].lz1) pushd(now);
    if(r<=tree[now<<1].r) change2(now<<1,l,r);
    else if(l>=tree[now<<1|1].l) change2(now<<1|1,l,r);
    else change2(now<<1,l,tree[now<<1].r),change2(now<<1|1,tree[now<<1|1].l,r);
    upd(now);
}
int search1(int now,int l,int r){//查连续0
    if(tree[now].l>=l&&tree[now].r<=r) {
        // cout<<tree[now].l<<' '<<tree[now].r<<' '<<tree[now].sum<<endl;
        return tree[now].sum;
    }
    if(tree[now].lz||tree[now].lz1) pushd(now);
    if(r<=tree[now<<1].r) return search1(now<<1,l,r);
    else if(l>=tree[now<<1|1].l) return search1(now<<1|1,l,r);
    else{
        int num1=0,num2=0;
        if(tree[now<<1].rsum>=tree[now<<1].r-l+1) num1=tree[now<<1].r-l+1;
        else num1=tree[now<<1].rsum;
        if(tree[now<<1|1].lsum>=r-tree[now<<1|1].l+1) num2=r-tree[now<<1|1].l+1;
        else num2=tree[now<<1|1].lsum;
        return max(max(search1(now<<1,l,tree[now<<1].r),search1(now<<1|1,tree[now<<1|1].l,r)),num1+num2);
    }
}
int search2(int now,int l,int r){//查区间1
    if(tree[now].l>=l&&tree[now].r<=r) return tree[now].gs;
    if(tree[now].lz||tree[now].lz1) pushd(now);
    if(r<=tree[now<<1].r) return search2(now<<1,l,r);
    else if(l>=tree[now<<1|1].l) return search2(now<<1|1,l,r);
    else return search2(now<<1,l,tree[now<<1].r)+search2(now<<1|1,tree[now<<1|1].l,r);
}
signed main(){
    scanf("%lld%lld",&n,&m);
    
    // for(int i=1;i<=n*4;i++) tree[i].l=tree[i].r=1;
    build(1,1,n);
    while(m--){
        // for(int i=1;i<=n;i++){
            // int k=search2(1,1,n);
        // }
        // cout<<endl;
        int op;
        scanf("%lld",&op);
        if(op==0){
            int x,y;
            scanf("%lld%lld",&x,&y);
            change1(1,x,y);
        }
        else if(op==1){
            int x,y,xx,yy;
            scanf("%lld%lld%lld%lld",&x,&y,&xx,&yy);
            int num=search2(1,x,y);
            // cout<<num<<endl;
            change1(1,x,y);
            if(num>=yy-xx+1-search2(1,xx,yy)){
                change2(1,xx,yy);
            }
            else{
                int l=xx-1,r=yy,res=0;
                while(l<=r){
                    int mid=(l+r)>>1;
                    if(mid-xx+1-search2(1,xx,mid)<=num) l=mid+1,res=mid;
                    else r=mid-1;
                }
                // cout<<xx<<" "<<res<<endl;
                if(res!=0) change2(1,xx,res);
            }
        }
        else{
            int x,y;
            scanf("%lld%lld",&x,&y);
            printf("%lld\n",search1(1,x,y));
        }
    }
    return 0;
}
2024/12/19 21:54
加载中...