刚学OI 1天,求助线段树
查看原帖
刚学OI 1天,求助线段树
538609
Neutralized楼主2022/6/27 08:08

样例第一行输出 2 ,,,
但是并没有发现更新策略的问题(
目前调不出来 /kel 求助

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;

#define ri register int
#define ll long long

//#define Neutral Shimokitazawa //rush!

#define Tp template<class T>
#ifdef Neutral
    const int End=1e6;
    char buf[End],*p1=buf,*p2=buf;
    #define g() (p1==p2&&(p2=(p1=buf)+fread(buf,1,End,stdin),p1==p2)?EOF:*p1++)
#else
    #define g() getchar()
#endif
#define pc(x) putchar(x)
#define isd(x) (x>=48&&x<=57)
namespace SlowIO{
    Tp inline void rd(T &x) {
        x=0; char i=g(); bool f=1;
        while(!isd(i)) f&=(i!='-'),i=g();
        while(isd(i)) x=(x<<3)+(x<<1)+(i^48),i=g();
        x*=((f<<1)-1);
    }
    const int OUT=1e6;
    static char outp[OUT]; int out;
    Tp inline void op(T x){
        out=0; x<0&&(x=-x,pc('-'));
        if(!x){ pc(48); return; }
        while(x) outp[++out]=x%10+48,x/=10;
        while(out) pc(outp[out--]);
    }
    Tp inline void writeln(T x){ op(x);pc('\n'); }
    Tp inline void writesp(T x){ op(x); pc(' '); }
    Tp inline void write(T x,char c=0){ op(x); c&&pc(c); }
}; using namespace SlowIO;

#define N 200003
int n,m;
struct node{
    int val,lef,rig;
    inline bool operator <(const node &a) const{ return val<a.val; }
    inline bool Emp(){ return val==0||lef>rig; } //是否为空
    inline bool operator ^(node a){ return !Emp()&&!a.Emp()&&(lef==a.rig+1||rig==a.lef-1); } //能否拼接
    inline node operator +(node a){ return {val+a.val,min(lef,a.lef),max(rig,a.rig)}; } //拼接
}; inline node Max(node a,node b){ return a<b?b:a; }
inline void Node(node t){ printf("[%d , %d] = %d\n",t.lef,t.rig,t.val); }
struct Ytz_Loves_15{
    node val[N<<2],Lef[N<<2],Rig[N<<2]; //区间内最长连续段,从左/右端点开始的最长连续段
    int cnt[N<<2],tag[N<<2],L[N<<2],R[N<<2]; //区间0的个数,区间左右端点
    #define len(u) (R[u]-L[u]+1)
    #define lef(u) (u<<1)
    #define rig(u) (u<<1|1)
    inline void Gen(int u){
        cnt[u]=cnt[lef(u)]+cnt[rig(u)];
        val[u]=Max(val[lef(u)],val[rig(u)]);
        Lef[u]=Lef[lef(u)]; if(Lef[u]^Lef[rig(u)]) Lef[u]=Lef[u]+Lef[rig(u)];
        Rig[u]=Rig[rig(u)]; if(Rig[lef(u)]^Rig[u]) Rig[u]=Rig[u]+Rig[lef(u)];
        val[u]=Max(val[u],Max(Lef[u],Rig[u]));
    }
    inline void Neg(int u){
        if(tag[u]==-1) return;
        tag[lef(u)]=tag[rig(u)]=tag[u];
        if(tag[u]){ //全部为1 长度全部设置为0
            cnt[lef(u)]=cnt[rig(u)]=0;
            val[lef(u)]=Lef[lef(u)]=Rig[lef(u)]={0,1,0};
            val[rig(u)]=Lef[rig(u)]=Rig[rig(u)]={0,1,0};
        } else{ //全满
            ri llen=len(lef(u)),rlen=len(rig(u));
            cnt[lef(u)]=llen,cnt[rig(u)]=rlen;
            val[lef(u)]=Lef[lef(u)]=Rig[lef(u)]={llen,L[lef(u)],R[lef(u)]};
            val[rig(u)]=Lef[rig(u)]=Rig[rig(u)]={rlen,L[rig(u)],R[rig(u)]};
        } tag[u]=-1; //?
    }
    inline void Bld(int u,int l,int r){
        L[u]=l,R[u]=r,tag[u]=-1;
        if(l==r){ val[u]=Lef[u]=Rig[u]={0,1,0},cnt[u]=0; return; }
        ri mid=l+r>>1; Bld(lef(u),l,mid),Bld(rig(u),mid+1,r);
    }
    inline void Mdf(int u,int l,int r,int d){
        if(L[u]>=l&&R[u]<=r){
            tag[u]=d; if(tag[u])
                cnt[u]=0,val[u]=Lef[u]=Rig[u]={0,1,0};
            else cnt[u]=len(u),val[u]=Lef[u]=Rig[u]={len(u),L[u],R[u]}; return;
        } Neg(u); ri mid=L[u]+R[u]>>1; if(l<=mid) Mdf(lef(u),l,r,d);
        if(r>mid) Mdf(rig(u),l,r,d); Gen(u);
    }
    inline node Qry(int u,int l,int r){
        if(L[u]>=l&&R[u]<=r) return val[u];
        Neg(u); ri mid=L[u]+R[u]>>1; node t={0,1,0};
        if(l<=mid) t=Qry(lef(u),l,r);
        if(r>mid){ node b=Qry(rig(u),l,r); if(t^b) t=t+b; else t=Max(t,b); }
        return t;
    }
    inline int Sum(int u,int l,int r){
        if(L[u]>=l&&R[u]<=r) return len(u)-cnt[u]; //1的个数
        Neg(u); ri mid=L[u]+R[u]>>1,t=0;
        if(l<=mid) t=Sum(lef(u),l,r);
        if(r>mid) t+=Sum(rig(u),l,r); return t;
    }
    inline void Debug(int u,int l,int r){
        if(l==r){writesp(!cnt[u]); return;}
        Neg(u); ri mid=l+r>>1;
        Debug(lef(u),l,mid),Debug(rig(u),mid+1,r);
    }
}tr; //O(n \log^2 n)
//#define debug neutral

int main()
{
    rd(n),rd(m);
    tr.Bld(1,1,n);
    while(m--){
        int cho,l,r,L,R;
        rd(cho),rd(l),rd(r);
        if(cho==0){
            tr.Mdf(1,l,r,0);
            #ifdef debug
                tr.Debug(1,1,n),pc('\n');
            #endif
        }
        if(cho==1){
            ri tot=tr.Sum(1,l,r); rd(L),rd(R);
            if(tot==0) continue;
            ri emp=R-L+1-tr.Sum(1,L,R); //有多少脑洞
            tr.Mdf(1,l,r,0); //挖走
            if(emp<=tot){
                tr.Mdf(1,L,R,1);
                #ifdef debug
                    tr.Debug(1,1,n),pc('\n');
                #endif
                continue; //可以全部填充
            } ri lef=L,rig=R,mid,res=L;
            while(lef<=rig){ //二分出可以填充的位置
                mid=lef+rig>>1; emp=mid-L+1-tr.Sum(1,L,mid);
                if(emp<=tot) res=mid,lef=mid+1;
                else rig=mid-1;
            } tr.Mdf(1,L,res,1); //全部填充为1
            #ifdef debug
                tr.Debug(1,1,n),pc('\n');
            #endif
        }
        if(cho==2){
            node t=tr.Qry(1,l,r);
            writeln(t.val);
        }
    }
    return 0;
}
2022/6/27 08:08
加载中...