线段树处理区间合并问题。
#include<stdio.h>
#define MAX 50010
#include<algorithm>
using namespace std;
int L[4*MAX+1],R[4*MAX+1],M[4*MAX+1],covered[4*MAX+1];
void pushup(int l,int r,int rt)
{
int k=R[rt<<1]+L[rt<<1|1]; int m=(l+r)/2;
if(L[rt<<1]==m-l+1) L[rt]=L[rt<<1]+L[rt<<1|1];
else L[rt]=L[rt<<1];
if(R[rt<<1|1]==r-m) R[rt]=R[rt<<1|1]+R[rt<<1];
else R[rt]=R[rt<<1|1];
M[rt]= max( max(M[rt<<1],M[rt<<1|1]), k );
}
void pushdown(int l,int r,int rt)
{
int m=(l+r)/2;
if( covered[rt]==-1 ) return;
covered[rt<<1]=covered[rt<<1|1]=covered[rt];
if( covered[rt]==1 )
{
L[rt<<1]=R[rt<<1]=M[rt<<1]=0;
L[rt<<1|1]=R[rt<<1|1]=M[rt<<1|1]=0;
}
if( covered[rt]==0 )
{
L[rt<<1]=R[rt<<1]=M[rt<<1]=m-l+1;
L[rt<<1|1]=R[rt<<1|1]=M[rt<<1|1]=r-m;
}
covered[rt]=-1;
}
void build(int l,int r,int rt)
{
L[rt]=R[rt]=M[rt]=r-l+1;
covered[rt]=-1;
if(l==r) return ;
int m=(l+r)/2;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
}
void update(int tag,int a,int b,int l,int r,int rt)
{
if( l==a && r==b )
{
if( tag==0 ){
L[rt]=R[rt]=M[rt]=r-l+1;
covered[rt]=tag;
}
else
{
covered[rt]=tag;
L[rt]=R[rt]=M[rt]=0;
}
return;
}
pushdown(l,r,rt);
int m=(l+r)/2;
if( b<=m ) update(tag,a,b,l,m,rt<<1);
else
if( a>m ) update(tag,a,b,m+1,r,rt<<1|1);
else
{
update(tag,a,m,l,m,rt<<1);
update(tag,m+1,b,m+1,r,rt<<1|1);
}
pushup(l,r,rt);
}
int query(int len,int l,int r,int rt)
{
if( l==r ) return 1;
int m=(l+r)/2;
pushdown(l,r,rt);
if( M[rt<<1]>=len ) return query(len,l,m,rt<<1);
else
if( R[rt<<1]+L[rt<<1|1] >= len ) return m-R[rt<<1]+1;
else
return query(len,m+1,r,rt<<1|1);
}
int main()
{
int i,j,k;int N,m;
scanf("%d%d",&N,&m);
build(1,N,1);
for(i=1;i<=m;i++)
{
scanf("%d",&j);
if(j==1)
{
int len;
scanf("%d",&len);
if( M[1]<len ) printf("0\n");
else
{
int ans=query(len,1,N,1);
update(1,ans,ans+len-1,1,N,1);
printf("%d\n",ans);
}
}
else
{
int s,len;
scanf("%d%d",&s,&len);
update(0,s,s+len-1,1,N,1);
}
}
return 0;
}