题目链接如下所示:
思路是这样,维护一个sum数组,记录区间内的空花瓶的数目,维护一个flag数组,给区间打上懒标记,如果是1,则代表是空花瓶标记,0则是有花瓶标记,-1表示对这个区间不做任何操作。
如果要插花,我们需要定位有f个空花瓶的区间,这可以用二分来找,即找从a开始的有f个空花瓶的区间,定位左区间用l=bin(a,1),定位右区间就是r=bin(l,f),注意这里的f如果比剩下到N-1总共的空花瓶要少时,需要把f换成num。
代码如下所示:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<vector>
#include<algorithm>
#include<cstring>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<cmath>
#include<climits>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int MAXN=50005;
int sum[MAXN<<2],flag[MAXN<<2];
int T,M,N;
void push_up(int rt){
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void push_down(int rt,int l,int r){
if (flag[rt]==-1) return;
flag[rt<<1]=flag[rt<<1|1]=flag[rt];
int mid=(l+r)>>1;
sum[rt<<1]=(mid-l+1)*flag[rt];
sum[rt<<1|1]=(r-mid)*flag[rt];
flag[rt]=-1;
}
void build(int l,int r,int rt){
if (l==r){
sum[rt]=1;
return;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
push_up(rt);
}
void update(int ul,int ur,int val,int l,int r,int rt){
if (ul<=l && r<=ur){
sum[rt]=val*(r-l+1);
flag[rt]=val;
return;
}
push_down(rt,l,r);
int mid=(l+r)>>1;
if (ul<=mid){
update(ul,ur,val,lson);
}
if (ur>mid){
update(ul,ur,val,rson);
}
push_up(rt);
}
int query(int ul,int ur,int l,int r,int rt){
if (ul<=l && r<=ur){
return sum[rt];
}
push_down(rt,l,r);
int ans=0;
int mid=(l+r)>>1;
if (ul<=mid){
ans+=query(ul,ur,lson);
}
if (ur>mid){
ans+=query(ul,ur,rson);
}
return ans;
}
int bin_search(int start,int sum){
int l=start, r=N;
while (l<=r){
int mid=(l+r)>>1;
int num= query(start,mid,1,N,1);
if (num>sum || (num==sum && query(mid,mid,1,N,1)==0)){
r=mid;
}else if (num<sum){
l=mid+1;
} else{
return mid;
}
}
return -1;
}
int main(){
int k,a,f,l,r;
scanf("%d",&T);
while (T--){
scanf("%d %d",&N,&M);
memset(flag,-1,sizeof(flag));
// cout<<flag[0]<<endl;
build(1,N,1);
// cout<<"T:"<<T<<",N:"<<N<<",M:"<<M<<endl;
while (M--){
scanf("%d",&k);
// cout<<"k:"<<k<<endl;
if (k==1){
scanf("%d %d",&a,&f);
// cout<<"k:"<<k<<",a:"<<a<<",f:"<<f<<endl;
a++;
int num= query(a,N,1,N,1);
// cout<<"num:"<<num<<endl;
if (num==0){
printf("Can not put any one.\n");
} else{
int spos= bin_search(a,1);
if (num<f) f=num;
int epos= bin_search(spos,f);
// cout<<"spos:"<<spos<<",epos:"<<epos<<endl;
update(spos,epos,0,1,N,1);
printf("%d %d\n",spos-1,epos-1);
}
} else{
scanf("%d %d",&l,&r);
// cout<<"k:"<<k<<",l:"<<l<<",r:"<<r<<endl;
l++,r++;
int ans=(r-l+1)- query(l,r,1,N,1);
printf("%d\n",ans);
update(l,r,1,1,N,1);
}
}
printf("\n");
}
return 0;
}