This question is the same as a hair and poj1823
I can refer to another problem solution
The only difference is that he is most looking left, then we can consider the more natural the better left
If the current lmax point to meet directly back
Otherwise, if the left son of the current point tmax meet, go to the left node
If it across the range, but also directly return
If the right son, his son went to the right
Note that I have already been sentenced and if not special, so once entered, it must meet.
#include<iostream> #include<queue> #include<map> #include<vector> #include<cstdio> #include<algorithm> #include<stack> using namespace std; typedef long long ll; const int N=1e6+10; const int inf=0x3f3f3f3f; struct node{ int l,r; int lazy; int tmax; int lmax; int rmax; }tr[N]; void pushup(int u){ tr[u].rmax=tr[u<<1|1].rmax; if(tr[u<<1|1].lazy==-1) tr[u].rmax+=tr[u<<1].rmax; tr[u].lmax=tr[u<<1].lmax; if(tr[u<<1].lazy==-1) tr[u].lmax+=tr[u<<1|1].lmax; tr[u].tmax=max(tr[u<<1].rmax+tr[u<<1|1].lmax,max(tr[u<<1].tmax,tr[u<<1|1].tmax)); if(tr[u<<1].lazy==tr[u<<1|1].lazy) tr[u].lazy=tr[u<<1].lazy; else{ tr[u].lazy=0; } } void build(int u,int l,int r){ if(l==r){ tr[u]=(node){l,l,-1,1,1,1}; } else{ tr[u]=(node){l,r,-1}; int mid=l+r>>1; build(u<<1,l,mid); build(u<<1|1,mid+1,r); pushup(u); } } void pushdown(int u){ tr[u<<1].lazy=tr[u<<1|1].lazy=tr[u].lazy; if(tr[u].lazy==1){ tr[u<<1].lmax=tr[u<<1].rmax=tr[u<<1].tmax=0; tr[u<<1|1].lmax=tr[u<<1|1].rmax=tr[u<<1|1].tmax=0; } else{ tr[u<<1].lmax=tr[u<<1].rmax=tr[u<<1].tmax=tr[u<<1].r-tr[u<<1].l+1; tr[u<<1|1].lmax=tr[u<<1|1].rmax=tr[u<<1|1].tmax=tr[u<<1|1].r-tr[u<<1|1].l+1; } tr[u].lazy=0; } void modify(int u,int l,int r,int x){ if(tr[u].l>=l&&tr[u].r<=r){ tr[u].lazy=x; if(x==1){ tr[u].lmax=tr[u].rmax=tr[u].tmax=0; } else{ tr[u].lmax=tr[u].rmax=tr[u].tmax=tr[u].r-tr[u].l+1; } return ; } if(tr[u].lazy!=0) pushdown(u); int mid=tr[u].l+tr[u].r>>1; if(l<=mid) modify(u<<1,l,r,x); if(r>mid){ modify(u<<1|1,l,r,x); } pushup(u); } int query(int u,int k){ if(tr[u].lmax>=k) return tr[u].l; if(tr[u<<1].tmax>=k) return query(u<<1,k); if(tr[u<<1].rmax+tr[u<<1|1].lmax>=k) return tr[u<<1].r-tr[u<<1].rmax+1; return query(u<<1|1,k); } int main(){ int n,m; cin>>n>>m; build(1,1,n); int i; for(i=1;i<=m;i++){ int c; scanf("%d",&c); if(c==1){ int k; scanf("%d",&k); if(tr[1].tmax<k){ printf("0\n"); continue; } int tmp=query(1,k); printf("%d\n",tmp); modify(1,tmp,tmp+k-1,1); } else{ int l,r; scanf("%d%d",&l,&r); modify(1,l,l+r-1,-1); } } }