zhuyuanchen520
题解:
操作1 : 1 A F
从A开始找出为0的花瓶并将F个蝴蝶挨个放进去,输出第一个放进去的花瓶,和最后一个放进去的花瓶
二分查询一个放进去的花瓶 fir (即第一个为0的花瓶,如果fir = n + 1 表示没有空的花瓶,输出Can not put any one.)
二分查询第一个使得空花瓶数达到F的花瓶位置 las
输出fir 和 las
并将 [fir,las] 覆盖1
操作2: 2 A B
输出 [A,B]的区间和
并将[A,B] 覆盖0
代码
#include
using namespace std;
const int maxn = 5e4+10;
typedef long long ll;
struct SegTree
{
int sum[maxn<<2],lz[maxn<<2],cnt[maxn<<2];
void init() {
memset(sum,0,sizeof(sum));
memset(lz,-1,sizeof(lz));
memset(cnt,0,sizeof(cnt));
}
void push_up(int rt) {
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
cnt[rt] = cnt[rt<<1] + cnt[rt<<1|1];
}
void push_down(int rt) {
if(lz[rt] == -1) return;
lz[rt<<1] = lz[rt<<1|1] = lz[rt];
sum[rt<<1] = lz[rt] * cnt[rt<<1];
sum[rt<<1|1] = lz[rt] * cnt[rt<<1|1];
lz[rt] = -1;
}
void build(int l,int r,int rt) {
if(l == r) {
cnt[rt] = 1;
return;
}
int mid = (l+r)>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
push_up(rt);
}
void update(int ql,int qr,int val,int l,int r,int rt) {
if(ql == l && qr == r) {
sum[rt] = val*cnt[rt];
lz[rt] = val;
return;
}
push_down(rt);
int mid = (l+r)>>1;
if(qr <= mid) update(ql,qr,val,l,mid,rt<<1);
else if(ql > mid) update(ql,qr,val,mid+1,r,rt<<1|1);
else {
update(ql,mid,val,l,mid,rt<<1);
update(mid+1,qr,val,mid+1,r,rt<<1|1);
}
push_up(rt);
}
int query(int ql,int qr,int l,int r,int rt) {
if(ql == l && qr == r) {
return sum[rt];
}
push_down(rt);
int mid = (l+r)>>1;
if(qr <= mid) return query(ql,qr,l,mid,rt<<1);
if(ql > mid) return query(ql,qr,mid+1,r,rt<<1|1);
return query(ql,mid,l,mid,rt<<1) + query(mid+1,qr,mid+1,r,rt<<1|1);
}
}seg;
int n,m;
bool check(int l,int mid,int tot)
{
int now = seg.query(l,mid,1,n,1);
int cha = mid - l + 1 - now;
return cha >= tot;
}
int main()
{
int caset;scanf("%d",&caset);
while(caset--)
{
scanf("%d%d",&n,&m);
seg.init();
seg.build(1,n,1);
while(m--)
{
int op,sta,tot;
scanf("%d%d%d",&op,&sta,&tot);
if(op == 1) {
int l = sta+1,r = n;
while(l <= r) {
int mid = (l + r)>>1;
if(seg.query(sta+1,mid,1,n,1) == mid - sta) l = mid + 1;
else r = mid - 1;
}
int fir = l; /// 找到第一个为0的位置
if(fir == n + 1) {
printf("Can not put any one.\n");
continue;
}
tot = min(tot,n-sta-seg.query(sta+1,n,1,n,1));
l = fir,r = n;
while(l <= r) {
int mid = (l+r)>>1;
if(check(fir,mid,tot)) r = mid - 1;
else l = mid + 1;
}
int las = l; /// 找到最后一个为0的位置 (总共tot个)
printf("%d %d\n",fir-1,las-1);
seg.update(fir,las,1,1,n,1);
}
else if(op == 2){
printf("%d\n",seg.query(sta+1,tot+1,1,n,1));
seg.update(sta+1,tot+1,0,1,n,1);
}
}
printf("\n");
}
return 0;
}