线段树区间合并经典题。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define rep(a,b,i) for(i=a;i<=b;i++)
#define maxn 50005
using namespace std;
struct pi{
int l;
int r;
int max;
int la;
}pp[4*maxn];
int mmax(int a,int b){
if(a>b)
return a;
return b;
}
void pushdown(int tot,int le,int ri){
if(pp[tot].la==0)
return ;
pp[2*tot+1].la=pp[2*tot+2].la=pp[tot].la;
pp[tot].la=0;
if(pp[2*tot+1].la==2) pp[2*tot+1].r=pp[2*tot+1].l=pp[2*tot+1].max=((le+ri)/2-le+1);
if(pp[2*tot+2].la==2) pp[2*tot+2].r=pp[2*tot+2].l=pp[2*tot+2].max=(ri-(le+ri)/2);
if(pp[2*tot+1].la==1) pp[2*tot+1].r=pp[2*tot+1].l=pp[2*tot+1].max=0;
if(pp[2*tot+2].la==1) pp[2*tot+2].r=pp[2*tot+2].l=pp[2*tot+2].max=0;
}
void build(int tot,int le,int ri){
pp[tot].l=ri-le+1;
pp[tot].r=ri-le+1;
pp[tot].max=ri-le+1;
pp[tot].la=2;
if(le==ri)
return ;
build(2*tot+1,le,(le+ri)/2);
build(2*tot+2,(le+ri)/2+1,ri);
}
void pushup(int tot,int le,int ri){
if(pp[2*tot+1].la==1)
pp[tot].l=0;
else
pp[tot].l=pp[2*tot+1].l;
if(pp[2*tot+2].la==1){
pp[tot].r=0;
}
else{
pp[tot].r=pp[2*tot+2].r;
}
if(!(pp[2*tot+1].la==1)&&pp[2*tot+1].l==(le+ri)/2-le+1){
if(!(pp[2*tot+2].la==1))
pp[tot].l+=pp[2*tot+2].l;
}
if(!(pp[2*tot+2].la==1)&&pp[2*tot+2].r==ri-(le+ri)/2){
if(!(pp[2*tot+1].la==1))
pp[tot].r+=pp[2*tot+1].r;
}
int p=0,q=0,f=0;
if(pp[2*tot+1].la==1){
p=0;
}
else if(pp[2*tot+1].la==2){
p=(le+ri)/2-le+1;
f+=p;
}
else{
p=pp[2*tot+1].max;
f+=pp[2*tot+1].r;
}
if(pp[2*tot+2].la==1)
q=0;
else if(pp[2*tot+2].la==2){
q=ri-(le+ri)/2;
f+=q;
}
else{
q=pp[2*tot+2].max;
f+=pp[2*tot+2].l;
}
pp[tot].max=mmax(mmax(p,q),f);
if(pp[tot].max==ri-le+1)
pp[tot].la=2;
if(pp[tot].max==0)
pp[tot].la=1;
return ;
}
void update1(int tot,int l,int r,int le,int ri){
if(l<=le&&r>=ri){
pp[tot].la=1;
pp[tot].r=pp[tot].l=pp[tot].max=0;
return ;
}
int mid=(le+ri)/2;
pushdown(tot,le,ri);
if(l<=mid)
update1(2*tot+1,l,r,le,mid);
if(r>mid)
update1(2*tot+2,l,r,mid+1,ri);
pushup(tot,le,ri);
}
void update2(int tot,int l,int r,int le,int ri){
if(l<=le&&r>=ri){
pp[tot].la=2;
pp[tot].r=pp[tot].l=pp[tot].max=(ri-le)+1;
return ;
}
pushdown(tot,le,ri);
int mid=(le+ri)/2;
if(l<=mid)
update2(2*tot+1,l,r,le,mid);
if(r>mid)
update2(2*tot+2,l,r,mid+1,ri);
pushup(tot,le,ri);
}
int query(int tot,int le,int ri,int p){
if(pp[tot].la==1)
return 0;
if(pp[tot].max<p)
return 0;
if(pp[tot].la==2)
return le;
int q;
q=query(2*tot+1,le,(le+ri)/2,p);
if(q)
return q;
int s=0,f=0;;
if(pp[2*tot+1].la!=1){
f=pp[2*tot+1].r;
s+=pp[2*tot+1].r;
}
if(pp[2*tot+2].la!=1)
s+=pp[2*tot+2].l;
if(s>=p)
return (le+ri)/2-f+1;
return query(2*tot+2,(le+ri)/2+1,ri,p);
}
int main()
{
int i,n,m,k,p,t;
while(cin>>n>>m)
{
build(0,1,n);
for(i=0;i<m;i++){
scanf("%d",&p);
if(p==1){
scanf("%d",&t);
k=query(0,1,n,t);
printf("%d\n",k);
if(k!=0){
update1(0,k,k+t-1,1,n);
}
}
else{
scanf("%d%d",&k,&p);
update2(0,k,k+p-1,1,n);
}
}
}
return 0;
}