线段树。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int MAXN = 50010;
int num[MAXN<<2],col[MAXN<<2];
void build(int l,int r,int rt)
{
col[rt]=0;//0表示该区间全为空位,1为占满,-1为其他情况
num[rt]=r-l+1;//表示该区间空位数
}
void pushdown(int l,int r,int rt)
{
int len=r-l+1;
if(col[rt]!=-1)
{
col[rt<<1]=col[rt<<1|1]=col[rt];
num[rt<<1]=col[rt]?0:(len-len/2);
num[rt<<1|1]=col[rt]?0:(len/2);
col[rt]=-1;
}
}
void pushup(int rt)
{
if(col[rt<<1]==col[rt<<1|1]&&col[rt<<1]!=-1)
col[rt]=col[rt<<1];
else col[rt]=-1;
num[rt]=num[rt<<1]+num[rt<<1|1];
}
int query1(int L,int R,int l,int r,int rt)//询问空位数
{
if(L>R) return 0;
if(L<=l&&r<=R)
return num[rt];
int m=(l+r)>>1;
int res=0;
pushdown(l,r,rt);
if(L<=m) res+=query1(L,R,lson);
if(m<R) res+=query1(L,R,rson);
return res;
}
int query2(int pos,int l,int r,int rt)//询问位置
{
if(l==r) return l;
int m=(l+r)>>1;
pushdown(l,r,rt);
if(pos<=num[rt<<1]) return query2(pos,lson);
else return query2(pos-num[rt<<1],rson);
}
void updata(int L,int R,int k,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
col[rt]=k;
num[rt]=(k?0:r-l+1);
return ;
}
int m=(l+r)>>1;
pushdown(l,r,rt);
if(L<=m) updata(L,R,k,lson);
if(m<R) updata(L,R,k,rson);
pushup(rt);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,q;
scanf("%d%d",&n,&q);
build(0,n-1,1);
while(q--)
{
int k,a,b;
scanf("%d%d%d",&k,&a,&b);
if(k==1)
{
int sy=query1(a,n-1,0,n-1,1);
//printf("sy=%d\n",sy);
if(sy==0) puts("Can not put any one.");
else
{
sy=min(sy,b);
int kw=query1(0,a-1,0,n-1,1);
int a1=query2(kw+1,0,n-1,1);
int a2=query2(kw+sy,0,n-1,1);
printf("%d %d\n",a1,a2);
updata(a1,a2,1,0,n-1,1);
}
}
else
{
printf("%d\n",b-a-query1(a,b,0,n-1,1)+1);
updata(a,b,0,0,n-1,1);
}
}
puts("");
}
return 0;
}