题目意思:
每一组的第一行有两个数n,m, n表示花瓶数量0~n-1,开始全为空,接下来有m组,每组有数k,a,b;当k=1时, 从a位置开始插花,b为花数量,当花瓶有花时,跳过当前,直到找到空花瓶再插入,输出插入第一支花的位置和最后一支花的位置,花可以没插完,当一支都没有插入则输出Can not put anyone.;当k=2时,清空【a,b】的花瓶,并输出在范围内花的数量。
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int maxn=50005;
struct node{
int sum,b;//sum表示该区间的花的数量,b为1时表示该区间的花瓶全满或则全空,否则b为0
}tree[maxn<<2];
int ql,qr,L,R,ans,n,m;
void build(int l,int r,int m)
{
int mid=(l+r)>>1;
tree[m].sum=0;tree[m].b=1;//一开始所有花瓶都是空的
if(l==r)return ;
build(l,mid,m<<1);
build(mid+1,r,m<<1|1);
}
void set_child(int l,int r,int m)
{
int mid=(l+r)>>1;
tree[m<<1].b=tree[m<<1|1].b=1;
if(tree[m].sum==r-l+1){
tree[m<<1].sum=mid-l+1;tree[m<<1|1].sum=r-mid;
}
else{
tree[m<<1].sum=0;tree[m<<1|1].sum=0;
}
}
void putinflower(int l,int r,int m)
{
if(ans<=0)return ;
int mid=(l+r)>>1;
if(l>=L&&r<=R&&tree[m].b==1){
if(!tree[m].sum){
ans-=(r-l+1);tree[m].sum=r-l+1;
if(ql<0)ql=l-1;//因为花瓶的标号是0到n-1,而建树的过程是1到n
qr=r-1;
}
else{//跳动插花范围的右边值,R刚好是插完花的右边范围的最小值,除非超出花瓶数量,则为n
R+=(r-l+1);if(R>n)R=n;
}
return ;
}
if(tree[m].b)
set_child(l,r,m);
tree[m].b=0;
if(L<=mid)putinflower(l,mid,m<<1);
if(R>mid)putinflower(mid+1,r,m<<1|1);
tree[m].sum=tree[m<<1].sum+tree[m<<1|1].sum;
if(tree[m].sum==r-l+1||!tree[m].sum)
tree[m].b=1;
}
void clears(int l,int r,int m)
{
// printf("%d\n",ans);
if(l>=L&&r<=R){
ans+=tree[m].sum;tree[m].b=1;tree[m].sum=0;
return ;
}
if(tree[m].b)
set_child(l,r,m);
tree[m].b=0;
int mid=(l+r)>>1;
if(L<=mid)clears(l,mid,m<<1);
if(R>mid)clears(mid+1,r,m<<1|1);
tree[m].sum=tree[m<<1].sum+tree[m<<1|1].sum;
if(tree[m].sum==r-l+1||!tree[m].sum)
tree[m].b=1;
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
build(1,n,1);
while(m--){
/*for(int i=0;i<4*n;i++){
printf("%d ",tree[i].sum);
}
printf("\n");*/
int op;
scanf("%d%d",&op,&L);L++;//因为建树的过程是从1到n
if(op==1){
scanf("%d",&ans);
R=L+ans-1;ql=qr=-1;
putinflower(1,n,1);
if(qr>=0)
printf("%d %d\n",ql,qr);
else
printf("Can not put any one.\n");
}
else{
scanf("%d",&R);R++;
ans=0;
clears(1,n,1);
printf("%d\n",ans);
}
}
printf("\n");
}
return 0;
}