hdu4614
hdu4614 Vases and Flowers
传送门
题意
有\(n(2\leq n\leq 50000)\)个花瓶,初始为空,有2种操作:
1.从花瓶\(a\)开始向后,在空的花瓶中插入一朵花,最多插入\(b\)朵花,判断是否可以插入至少一朵花,如果可以,计算第一个插花的花瓶编号和最后一个插花的花瓶编号
2.将\([a,b]\)内的花清空,计算清空的花朵数量
题解
线段树维护区间内空花瓶的数量
对于操作1,首先判断\([a,n]\)区间内的空花瓶数量是否为零,如果不为零,二分查找左端点,再二分查找右端点
对于操作2,直接查询\([a,b]\)区间内的空花瓶数量,区间长度减去空花瓶数量为花朵数量
#include<iostream>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<cstring>
#include<string>
#include<sstream>
#include<cmath>
#include<ctime>
#include<climits>
#include<algorithm>
#define LL long long
#define PII pair<int,int>
#define PLL pair<LL,LL>
#define PLI pair<LL,int>
#define pi acos(-1.0)
#define eps 1e-6
#define lowbit(x) x&(-x)
using namespace std;
const int maxn=50010;
int T,n,m,tree[4*maxn],lazy[4*maxn];
void pushup(int o){
tree[o]=tree[o<<1]+tree[o<<1|1];
}
void build(int o,int l,int r){
lazy[o]=-1;
if(l==r){
tree[o]=1;
return;
}
int mid=(l+r)>>1;
build(o<<1,l,mid);
build(o<<1|1,mid+1,r);
pushup(o);
}
void puttag(int o,int l,int r,int v){
lazy[o]=v;
tree[o]=v*(r-l+1);
}
void pushdown(int o,int l,int r){
if(lazy[o]==-1) return;
lazy[o<<1]=lazy[o];
lazy[o<<1|1]=lazy[o];
int mid=(l+r)>>1;
tree[o<<1]=lazy[o]*(mid-l+1);
tree[o<<1|1]=lazy[o]*(r-mid);
lazy[o]=-1;
}
void change(int o,int l,int r,int ql,int qr,int v){
if(ql<=l && r<=qr){
puttag(o,l,r,v);
return;
}
int mid=(l+r)>>1;
pushdown(o,l,r);
if(ql<=mid) change(o<<1,l,mid,ql,qr,v);
if(qr>mid) change(o<<1|1,mid+1,r,ql,qr,v);
pushup(o);
}
int query(int o,int l,int r,int ql,int qr){
if(ql<=l && r<=qr) return tree[o];
int mid=(l+r)>>1;
pushdown(o,l,r);
int ans=0;
if(ql<=mid) ans+=query(o<<1,l,mid,ql,qr);
if(qr>mid) ans+=query(o<<1|1,mid+1,r,ql,qr);
return ans;
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d %d",&n,&m);
build(1,1,n);
while(m--){
int k,a,b;
scanf("%d %d %d",&k,&a,&b);
if(k==1){
a++;
int sum=query(1,1,n,a,n);
if(sum==0) printf("Can not put any one.\n");
else{
int st,ed;
int l=a,r=n;
while(r>l){
int mid=(l+r)>>1;
if(query(1,1,n,a,mid)>=1) r=mid;
else l=mid+1;
}
st=r;
l=st;
r=n;
b=min(b,sum);
while(r>l){
int mid=(l+r)>>1;
if(query(1,1,n,st,mid)>=b) r=mid;
else l=mid+1;
}
ed=r;
printf("%d %d\n",st-1,ed-1);
change(1,1,n,st,ed,0);
}
}
else{
a++;
b++;
printf("%d\n",b-a+1-query(1,1,n,a,b));
change(1,1,n,a,b,1);
}
}
printf("\n");
}
}