蒟蒻求助整体二分,调了已经2天了,救救孩子吧
查看原帖
蒟蒻求助整体二分,调了已经2天了,救救孩子吧
311306
dk_qwq楼主2023/2/23 16:43

RT,只过了#10,目前发现问题:solve中的r用pow(2,63)样例都会寄

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
namespace INPUT{
    char buf[1<<20],*p1,*p2;
    #define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
}
using namespace INPUT;
template<typename T>
inline T read(){
    T x=0,p=1;
    char ch=gc();
    for(;ch<'0'||ch>'9';ch=gc())
        if(ch=='-') p=-1;
    for(;ch>='0'&&ch<='9';ch=gc())
        x=(x<<3)+(x<<1)+(ch^48);
    return x*p;
}
const int N=5e4+5;
struct SegmentTree{
    #define lc (o<<1)
    #define rc (o<<1|1)
    struct node{
        int l,r,sum;
        int lazytag;
    }t[N<<2];
    void build(int o,int l,int r){
        t[o].l=l,t[o].r=r;
        if(l==r) return ;
        int mid=(l+r)>>1;
        build(lc,l,mid),build(rc,mid+1,r);
    }
    void pushup(int o){
        t[o].sum=t[lc].sum+t[rc].sum;
    }
    void push(int o,int x){
        if(x==-1) t[o].sum=0,t[o].lazytag=x;
        else {
            if(t[o].lazytag==-1) t[o].lazytag=x;
            else t[o].lazytag+=x;
            t[o].sum+=x*(t[o].r-t[o].l+1);
        }
    }
    void pushdown(int o){
        if(!t[o].lazytag) return ;
        push(lc,t[o].lazytag),push(rc,t[o].lazytag);
        t[o].lazytag=0;
    }
    void add(int o,int ql,int qr,int x){
        if(ql<=t[o].l&&t[o].r<=qr) {push(o,x);return ;}
        pushdown(o);
        int mid=(t[o].l+t[o].r)>>1;
        if(ql<=mid) add(lc,ql,qr,x);
        if(mid<qr) add(rc,ql,qr,x);
        pushup(o);
    }
    int query(int o,int ql,int qr){
        if(ql<=t[o].l&&t[o].r<=qr) return t[o].sum;
        pushdown(o);
        int mid=(t[o].l+t[o].r)>>1;
        int ans=0;
        if(ql<=mid) ans+=query(lc,ql,qr);
        if(mid<qr) ans+=query(rc,ql,qr);
        pushup(o);
        return ans;
    }
    #define add(ql,qr,x) add(1,ql,qr,x)
    #define query(ql,qr) query(1,ql,qr)
}T;
int n,m;
#define ll long long
struct Query{
    int id;
    int l,r;
    ll c;
    Query(){}
    Query(int id,int l,int r,ll c):
        id(id),l(l),r(r),c(c){}
}q[N<<1],q1[N<<1],q2[N<<1];
int ans[N];
void solve(ll l,ll r,int ql,int qr){
    if(ql>qr||l>r) return ;
    if(l==r){
        for(int i=ql;i<=qr;i++)
            if(q[i].id) ans[q[i].id]=l;
        return ;
    }
    ll mid=(l+r)>>1;
    int cnt1=0,cnt2=0;
    for(int i=ql;i<=qr;i++){
        if(q[i].id){
            ll x=T.query(q[i].l,q[i].r);
            if(x>=q[i].c) q2[++cnt2]=q[i];
            else q[i].c-=x,q1[++cnt1]=q[i];
        }
        else{
            if(q[i].c>mid) q2[++cnt2]=q[i],T.add(q[i].l,q[i].r,1);
            else q1[++cnt1]=q[i];
        }
    }
    T.add(1,n,-1);
    for(int i=1;i<=cnt1;i++) q[ql+i-1]=q1[i];
    for(int i=1;i<=cnt2;i++) q[ql+cnt1+i-1]=q2[i];
    solve(l,mid,ql,ql+cnt1-1),solve(mid+1,r,ql+cnt1,qr);
}
ll pow(ll x,int k){
    ll ans=1;
    while(k){
        if(k&1) ans*=x;
        x*=x,k>>=1;
    }
    return ans;
}
int main(){
    // freopen("P3332.in","r",stdin);
    // freopen("P3332.out","w",stdout);
    n=read<int>(),m=read<int>();
    T.build(1,1,n);
    for(int i=1;i<=m;i++){
        int opt=read<int>();
        int l=read<int>(),r=read<int>();
        if(opt==1) q[i]=Query(0,l,r,read<int>());
        else q[i]=Query(i,l,r,read<int>());
    }
    solve(1,pow(2,62),1,m);
    for(int i=1;i<=m;i++)
        if(ans[i]) printf("%d\n",ans[i]);
}
2023/2/23 16:43
加载中...