线段树保存区间空位数,区间最左空位和区间最右空位
放入花时从A点到n点从左到右查询空位,并记录最左和最右的空位,最后统一将最左到最右更新为没有空位
查询时用位置总数前去空位数就是花的个数,并且将区间更新为全为空位
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int maxn=50000+10; //数组大小
int sum[maxn<<2],lm[maxn<<2],rm[maxn<<2];
int lazy[maxn<<2];
void PushUp(int rt) //向上更新父节点
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
if(lm[rt<<1]==-1) lm[rt]=lm[rt<<1|1];
else lm[rt]=lm[rt<<1];
if(rm[rt<<1|1]==-1) rm[rt]=rm[rt<<1];
else rm[rt]=rm[rt<<1|1];
}
void PushDown(int rt,int l,int r)
{
if(lazy[rt]==1)
{
int m=(l+r)>>1;
int num=r-l+1;
lazy[rt<<1]=lazy[rt<<1|1]=1;
sum[rt<<1]=num%2==0?num/2:(num/2+1);
sum[rt<<1|1]=num-sum[rt<<1];
lm[rt<<1]=l;
rm[rt<<1]=m;
lm[rt<<1|1]=m+1;
rm[rt<<1|1]=r;
lazy[rt]=0;
}
if(lazy[rt]==-1)
{
lazy[rt<<1]=lazy[rt<<1|1]=-1;
sum[rt<<1]=0;
sum[rt<<1|1]=0;
lm[rt<<1]=-1;
rm[rt<<1]=-1;
lm[rt<<1|1]=-1;
rm[rt<<1|1]=-1;
lazy[rt]=0;
}
}
void build(int l,int r,int rt) //建树
{
lazy[rt]=0;
if(l==r)
{
sum[rt]=1;
lm[rt]=rm[rt]=l;
return;
}
int m=(l+r)>>1;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
PushUp(rt);
}
int ans;
void update(int L,int R,int f,int l,int r,int rt)
{
if(L>r||R=L&&r<=R)
{
ans+=r-l+1-sum[rt];
if(f==1)
{
sum[rt]=r-l+1;
lm[rt]=l;
rm[rt]=r;
}
else
{
sum[rt]=0;
lm[rt]=rm[rt]=-1;
}
lazy[rt]=f;
return;
}
PushDown(rt,l,r);
int m=(l+r)>>1;
if(L<=m) update(L,R,f,l,m,rt<<1);
if(R>m) update(L,R,f,m+1,r,rt<<1|1);
PushUp(rt);
}
int n,m,a,b,c;
int ml,mr,num;
void query(int L,int R,int l,int r,int rt)
{
if(L>r||R=L&&r<=R&&sum[rt]<=num)
{
num-=sum[rt];
ml=min(lm[rt],ml);
mr=max(rm[rt],mr);
return;
}
PushDown(rt,l,r);
int m=(l+r)>>1;
if(m>=L&&sum[rt<<1]) query(L,R,l,m,rt<<1);
if(R>m&&sum[rt<<1|1]) query(L,R,m+1,r,rt<<1|1);
}
int main()
{
//freopen("/home/zlwang/test.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
build(1,n,1);
for(int i=0;imr) printf("Can not put any one.\n");
else
{
printf("%d %d\n",ml-1,mr-1);
update(ml,mr,-1,1,n,1);
}
}
else if(a==2)
{
ans=0;
update(b+1,c+1,1,1,n,1);
printf("%d\n",ans);
}
}
printf("\n");
}
return 0;
}