二分细节注意
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e4+5;
int n,m,a[maxn];
//花瓶里有花就不能插.一个花瓶只能有一朵花. 所以val不存花瓶里的花数
struct tt{
int lazy;//初始为-1,全空为1,全满为0
int val;//存空花瓶数 !!
}t[maxn<<2];
void pushup(int rt){
t[rt].val=t[rt<<1].val+t[rt<<1|1].val;
}
void build(int rt,int l,int r){
t[rt].lazy=-1;
t[rt].val=r-l+1;//存rt的整个区间的空花瓶数
if(l==r) return;//若val只在叶节点赋值则写在if里
int mid=(l+r)>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
pushup(rt);
}
void pushdown(int rt,int ln,int rn){
if(t[rt].lazy!=-1){
t[rt<<1].lazy=t[rt].lazy;
t[rt<<1|1].lazy=t[rt].lazy;
t[rt<<1].val=t[rt].lazy*ln;
t[rt<<1|1].val=t[rt].lazy*rn;
t[rt].lazy=-1;
}
}
//z=0时:lazy=0全满,val=0空花瓶数为0
void update(int L,int R,int z,int rt,int l,int r){
if(R<l||L>r) return;
if(L<=l&&r<=R){
t[rt].val=z*(r-l+1);
t[rt].lazy=z;
return;
}
//if(l==r) return;
int mid=(l+r)>>1;
pushdown(rt,mid-l+1,r-mid);
if(L<=mid) update(L,R,z,rt<<1,l,mid);
if(R>mid) update(L,R,z,rt<<1|1,mid+1,r);
pushup(rt);
}
int que(int L,int R,int rt,int l,int r){
if(L>r||R<l) return 0;
if(L<=l&&r<=R)
return t[rt].val;
int ans=0;
int mid=(l+r)>>1;
pushdown(rt,mid-l+1,r-mid);
ans+=(que(L,R,rt<<1,l,mid)+que(L,R,rt<<1|1,mid+1,r));
return ans;
}
int bs(int x,int num){
int l=x,r=n;
int mid,ans=0;
while(l<=r){
mid=(l+r)>>1;
//不能一等于就break,因为可能1-3区间有两个,但第三个不是,所以1-2也是两个,所以取2。所以还要让r变小让他走下去
// if(que(x,mid,1,1,n)==num) ans=mid,r=mid-1;//位置等于右端值
// if(que(x,mid,1,1,n)>num) r=mid-1; //错误
if(que(x,mid,1,1,n)>=num) ans=mid,r=mid-1;
//是x不是l!!所以开始时得定义l=x ,不能改变x,因为永远要从x开始
else l=mid+1;
}
return ans;
}
int main(){
int T,x,y,z;
cin>>T;
while(T--){
cin>>n>>m;
build(1,1,n);
while(m--){
scanf("%d%d%d",&x,&y,&z);
if(x==1){
y++;//花瓶 编号从0开始。所以输出的时候也要减去
int cnt=que(y,n,1,1,n);
if(!cnt)
printf("Can not put any one.\n");
else{
int L=bs(y,1);//从y开始找第1个花瓶为空的位置
int R=bs(y,min(cnt,z));//找最后一个
update(L,R,0,1,1,n);
printf("%d %d\n",L-1,R-1);
}
}
else {
//这个区间最多有这么多花,减去空花瓶即没花的数量,就是这个区间的花的数量
y++;z++;
printf("%d\n",z-y+1-que(y,z,1,1,n));
update(y,z,1,1,1,n);
}
}
puts("");
}
}