思路:整体二分套CDQ+线段树,但是莫名其妙RE了。求助/kel
#include<algorithm>
#include<cstdio>
const int M=5e4+5;
typedef long long ll;
int n,m,ans[M],a[M<<2],add[M<<2];
bool lazy[M<<2];
struct Node{
int opt,L,R,id;
ll k;
}t[M],tmp1[M],tmp2[M];
inline void pushdown(const int&u,const int&L,const int&R){
if(L==R)return;
if(lazy[u]){
a[u<<1]=a[u<<1|1]=0;
add[u<<1]=add[u<<1|1]=0;
lazy[u<<1]=lazy[u<<1|1]=true;
lazy[u]=false;
}
if(add[u]){
int mid=L+R>>1;
add[u<<1]+=add[u];
add[u<<1|1]+=add[u];
a[u<<1]+=(mid-L+1)*add[u];
a[u<<1|1]+=(R-mid)*add[u];
add[u]=0;
}
}
void Modify(int u,int l,int r,int L=-n,int R=n){
if(L>r||l>R)return;
pushdown(u,L,R);
if(L>=l&&R<=r){
++add[u];
a[u]+=R-L+1;
}
else{
int mid=L+R>>1;
Modify(u<<1,l,r,L,mid);
Modify(u<<1|1,l,r,mid+1,r);
}
}
int Query(int u,int l,int r,int L=-n,int R=n){
if(L>r||l>R)return 0;
pushdown(u,L,R);
int mid=L+R>>1;
if(L>=l&&R<=r)return a[u];
return Query(u<<1,l,r,L,mid)+Query(u<<1|1,l,r,mid+1,R);
}
void Solve(int L,int R,int Vl,int Vr){
int i,mid=Vl+Vr>>1,cnt1=0,cnt2=0;
if(L==R)return;
if(Vl==Vr){
for(i=L;i<=R;++i){
if(t[i].opt==2)ans[t[i].id]=Vl;
}
return;
}
for(i=L;i<=R;++i){
if(t[i].opt==1){
if(t[i].k>mid){
Modify(1,t[i].L,t[i].R);
tmp2[++cnt2]=t[i];
}
else{
tmp1[++cnt1]=t[i];
}
}
else{
int num=Query(1,t[i].L,t[i].R);
if(num>=t[i].k){
tmp2[++cnt2]=t[i];
}
else{
t[i].k-=num;
tmp1[++cnt1]=t[i];
}
}
}
lazy[1]=true;a[1]=add[1]=0;
for(i=1;i<cnt1+L;++i)t[i]=tmp1[i-L+1];
for(i=1;i<=cnt2;++i)t[i+L+cnt1-1]=tmp2[i];
Solve(L,R-cnt2,Vl,mid);
Solve(L+cnt1,R,mid+1,Vr);
}
signed main(){
int i,tot=0;
scanf("%d%d",&n,&m);
for(i=1;i<=m;++i){
scanf("%d%d%d%lld",&t[i].opt,&t[i].L,&t[i].R,&t[i].k);
if(t[i].opt==2)t[i].id=++tot;
}
Solve(1,m,-n,n);
for(i=1;i<=tot;++i)printf("%d\n",ans[i]);
}