题意:
见后文翻译。
思路:
线段树,查询区间和,修改区间和。根据数据量要求,需要加入 lazy 。
可插入处标记为 1 ,否则为 0 。
代码:
#include <bits/stdc++.h>
using namespace std;
#define ls l,mid,rt*2
#define rs mid+1,r,rt*2+1
#define mi (l+r)/2
#define sf l,r,rt
const int MAXN=5e5+500;
int tree[MAXN*4],lazy[MAXN*4],upst,upen,st,en,v,n,m,T,x,y,z,ans;
bool flag;
bool check1(int l,int r,int rt){
if(flag||tree[rt]==0) return 0;
return 1;
}
bool check2(int l,int r,int rt){
if(tree[rt]==(r-l+1)&&tree[rt]<=v) return 1;
return 0;
}
void push_down(int l,int r,int rt){
int mid=mi;
if(lazy[rt]==1){
lazy[rt*2]=lazy[rt*2+1]=1;
tree[rt]=r-l+1;
tree[rt*2]=mi-l+1;
tree[rt*2+1]=r-mid;
}
if(lazy[rt]==0){
lazy[rt*2]=lazy[rt*2+1]=0;
tree[rt]=tree[rt*2+1]=tree[rt*2]=0;
}
lazy[rt]=-1;
}
void push_up(int l,int r,int rt){
tree[rt]=tree[rt*2]+tree[rt*2+1];
if(lazy[rt*2]==lazy[rt*2+1]){
lazy[rt]=lazy[rt*2];
lazy[rt*2]=lazy[rt*2+1]=-1;
}
return ;
}
void build(int l,int r,int rt){
if(l==r){
tree[rt]=1;lazy[rt]=-1;
return ;
}
int mid=mi;
build(ls);
build(rs);
push_up(sf);
return ;
}
void update(int l,int r,int rt){
if(st>r||en<l) return ;
push_down(sf);
if(st<=l&&r<=en){
lazy[rt]=v;
if(v==1){
tree[rt]=r-l+1;
}else{
tree[rt]=0;
}
return ;
}
int mid=mi;
update(ls);
update(rs);
push_up(sf);
return ;
}
int query2(int l,int r,int rt){
if(st>r||en<l) return 0;
push_down(sf);
if(st<=l&&r<=en){
return tree[rt];
}
int mid=mi;
int ans=0;
ans+=query2(ls);
ans+=query2(rs);
push_up(sf);
return ans;
}
void query1(int l,int r,int rt){
if(st>r||en<l||!check1(sf)) return ;
push_down(sf);
if(st<=l&&r<=en&&check2(sf)){
v-=tree[rt];
ans=r;
if(v==0) flag=1;
return ;
}
int mid=mi;
query1(ls);
query1(rs);
push_up(sf);
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
build(1,n,1);
while(m--){
scanf("%d%d%d",&x,&y,&z);
if(x==1){
y++;
st=y;v=1;en=n;ans=-1;flag=0;
query1(1,n,1);
if(ans==-1){
printf("Can not put any one.\n");
continue;
}
upst=ans;
v=z;ans=-1;flag=0;
query1(1,n,1);
if(ans==-1) upen=upst;
else upen=ans;
printf("%d %d\n",upst-1,upen-1);
st=upst;en=upen;
v=0;
update(1,n,1);
}else{
y++;z++;
st=y;en=z;v=1;
cout<<(en-st+1)-query2(1,n,1)<<endl;
update(1,n,1);
}
//debug();
}
cout<<endl;
}
}
翻译非原创
第一行一个整数T,表示数据组数。
每组数据,第一行一个整数N(1 < N < 50001) and M(1 < M < 50001). N 是花瓶个数, M是Alice的操作次数. 接下来M行 行3个 整数. 第一个整数 K(1 or 2). 如果K=1, 后面跟两个整数 A 和 F . 表示Alice 得到了F 朵花并且把它们放入从A 的花瓶里. 如果K= 2, 后跟两个整数 A 和 B. 表示Alice 清理的花瓶标号范围(A <= B).
对于每个K=1的操作,输出第一朵和最后一朵花放置的花瓶标号。如果没有任何放花的位置,输出'Can not put any one.'.对于K=2的操作,输出丢弃花的个数.
每组数据后输出一个空行.
2 10 5 1 3 5 2 4 5 1 1 8 2 3 6 1 8 8 10 6 1 2 5 2 3 4 1 0 8 2 2 5 1 4 4 1 2 3
3 7 2 1 9 4 Can not put any one. 2 6 2 0 9 4 4 5 2 3