题目大意:n个花瓶,m个操作,花瓶里面有的有花,有的是空的。1操作是从a开始往右放b朵花,花瓶有了的不放,跳过,直到a右边都放满了花,多余的扔了。输出本次放花的起始位置,如果一朵不能放,输出一句话。
2操作是清除区间[a,b]的花。并输出清除了多少花。
题目分析:简单线段树。只需要维护区间和即可。对于1操作求起始位置,二分位置即可,对于操作2,统计求和即可。
详情请见代码:
#include
#include
#include
using namespace std;
const int N = 50005;
int n,m;
struct node
{
int sum,lazy;
}tree[N<<2];
void build(int num,int s,int e)
{
tree[num].sum = 0;
tree[num].lazy = -1;
if(s == e)
return;
int mid = (s + e)>>1;
build(num<<1,s,mid);
build(num<<1|1,mid + 1,e);
}
void pushup(int num)
{
tree[num].sum = tree[num<<1].sum + tree[num<<1|1].sum;
}
void pushdown(int num,int s,int e)
{
tree[num<<1].lazy = tree[num<<1|1].lazy = tree[num].lazy;
if(tree[num].lazy)
{
int mid = (s + e)>>1;
tree[num<<1].sum = mid - s + 1;
tree[num<<1|1].sum = e - mid;
}
else
tree[num<<1].sum = tree[num<<1|1].sum = 0;
tree[num].lazy = -1;
}
void update(int num,int s,int e,int l,int r,int val)
{
if(s == l && r == e)
{
tree[num].lazy = val;
if(val)
tree[num].sum = e - s + 1;
else
tree[num].sum = 0;
return;
}
if(tree[num].lazy > -1)
pushdown(num,s,e);
int mid = (s + e)>>1;
if(r <= mid)
update(num<<1,s,mid,l,r,val);
else
{
if(l > mid)
update(num<<1|1,mid + 1,e,l,r,val);
else
{
update(num<<1,s,mid,l,mid,val);
update(num<<1|1,mid + 1,e,mid + 1,r,val);
}
}
pushup(num);
}
int query(int num,int s,int e,int l,int r)
{
if(s == l && e == r)
return tree[num].sum;
if(tree[num].lazy > -1)
pushdown(num,s,e);
int mid = (s + e)>>1;
if(r <= mid)
return query(num<<1,s,mid,l,r);
else
{
if(l > mid)
return query(num<<1|1,mid + 1,e,l,r);
else
return query(num<<1,s,mid,l,mid) + query(num<<1|1,mid + 1,e,mid + 1,r);
}
}
int bin(int s,int rank)
{
int l = s;
int r = n;
int ans = -1;
int mid;
while(l <= r)
{
int mid = (l + r)>>1;
int tmp = query(1,1,n,s,mid);
if(tmp + rank == mid - s + 1)
{
ans = mid;
r = mid - 1;
}
else
{
if(tmp + rank < mid - s + 1)
r = mid - 1;
else
l = mid + 1;
}
}
return ans;
}
int main()
{
int i,t;
int op,a,b;
scanf("%d",&t);
while(t --)
{
scanf("%d%d",&n,&m);
build(1,1,n);
while(m --)
{
scanf("%d%d%d",&op,&a,&b);
if(op == 1)
{
int st,ed;
a ++;
st = bin(a,1);
if(st == -1)
puts("Can not put any one.");
else
{
int tmp = query(1,1,n,st,n);
tmp = n - st + 1 - tmp;
if(tmp <= b)
b = tmp;
ed = bin(a,b);
printf("%d %d\n",st - 1,ed - 1);
update(1,1,n,st,ed,1);
}
}
else
{
a ++;b ++;
printf("%d\n",query(1,1,n,a,b));
update(1,1,n,a,b,0);
}
}
puts("");
}
return 0;
}
//890MS 1256K