rt,n<=50000,然后我开了四倍空间,但是为啥这份代码会 RE,附:开 40 被过了。
#include<iostream>
using namespace std;
const int N=50010;
struct SegmentTree{
int sum,len;
int lmax,rmax;
int tag;
#define sum(p) tree[p].sum
#define len(p) tree[p].len
#define lmax(p) tree[p].lmax
#define rmax(p) tree[p].rmax
#define tag(p) tree[p].tag//-1 退房 1 入住
}tree[N<<2];
int n,m;
void pushup(int p){
if(sum(p<<1)==len(p<<1)) lmax(p)=len(p<<1)+lmax(p<<1|1);
else lmax(p)=lmax(p<<1);
if(sum(p<<1|1)==len(p<<1|1)) rmax(p)=len(p<<1|1)+rmax(p<<1);
else rmax(p)=rmax(p<<1|1);
sum(p)=max(rmax(p<<1)+lmax(p<<1|1),max(sum(p<<1),sum(p<<1|1)));
}
void pushdown(int p){
if(tag(p)==0) return ;
if(tag(p)==1){
tag(p<<1)=tag(p<<1|1)=1;
sum(p<<1)=sum(p<<1|1)=0;
lmax(p<<1)=lmax(p<<1|1)=0;
rmax(p<<1)=rmax(p<<1|1)=0;
}
if(tag(p)==-1){
tag(p<<1)=tag(p<<1|1)=-1;
sum(p<<1)=lmax(p<<1)=rmax(p<<1)=len(p<<1);
sum(p<<1|1)=lmax(p<<1|1)=rmax(p<<1|1)=len(p<<1|1);
}
tag(p)=0;
}
void build(int p,int l,int r){
sum(p)=lmax(p)=rmax(p)=len(p)=r-l+1;
if(l==r) return ;
int mid=l+r>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
// pushup(p);
}
void change(int p,int l,int r,int ll,int rr,int st){
pushdown(p);
if(ll<=l && r<=rr){
if(st==1) sum(p)=lmax(p)=rmax(p)=0;
else sum(p)=lmax(p)=rmax(p)=len(p);
tag(p)=st;
return ;
}
int mid=l+r>>1;
if(ll<=mid) change(p<<1,l,mid,ll,rr,st);
if(rr>mid) change(p<<1|1,mid+1,r,ll,rr,st);
pushup(p);
}
int query(int p,int l,int r,int k){
pushdown(p);
if(l==r) return l;
int mid=l+r>>1;
if(sum(p<<1)>=k) return query(p<<1,l,mid,k);
if(rmax(p<<1)+lmax(p<<1|1)>=k) return mid-rmax(p<<1)+1;
else return query(p<<1|1,mid+1,r,k);
}
int main(){
int n,m; cin>>n>>m;
build(1,1,n);
while(m--){
int opt; scanf("%d",&opt);
if(opt==1){
int x; scanf("%d",&x);
if(sum(1)>=x){
int ans=query(1,1,n,x);
change(1,1,n,ans,ans+x-1,1);
printf("%d\n",ans);
}
else cout<<0<<endl;
}
else{
int x,y; scanf("%d%d",&x,&y);
change(1,1,n,x,x+y-1,-1);
}
}
return 0;
}