题意:给你n个花瓶,m次操作,若k==1,则从第A个开始插入花,直到插入了F朵花或者没有空花瓶了,若k==2,则将花瓶a~b清空。
思路:比较裸的线段树,对于第一种操作,若能插花则先求出插花的左右边界,然后将这个区间空位更新为0,第二种操作,询问区间花瓶数后直接将此区间空位更新为区间的r-l+1.
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <cstdlib>
#include <algorithm>
using namespace std;
typedef __int64 int64;
typedef long long ll;
#define M 50005
#define N 1000005
#define max_inf 0x7f7f7f7f
#define min_inf 0x80808080
#define mod 1000000007
struct node
{
int l , r , sum , fg;
}tree[4*M];
int n , m;
void Build(int rt , int l ,int r)
{
tree[rt].l = l;
tree[rt].r = r;
tree[rt].sum = r-l+1;
tree[rt].fg = -1;
if (l == r)return;
int mid = (l+r)>>1;
Build(rt<<1,l,mid);
Build(rt<<1|1,mid+1,r);
}
void Updata_down(int rt)
{
if (tree[rt].fg != -1)
{
tree[rt<<1].fg = tree[rt<<1|1].fg = tree[rt].fg;
tree[rt<<1].sum = tree[rt].fg*(tree[rt<<1].r-tree[rt<<1].l+1);
tree[rt<<1|1].sum = tree[rt].fg*(tree[rt<<1|1].r-tree[rt<<1|1].l+1);
tree[rt].fg = -1;
}
}
int Query(int rt , int l , int r)
{
if (tree[rt].l == l && tree[rt].r == r)return tree[rt].sum;
Updata_down(rt);
int mid = (tree[rt].l+tree[rt].r)>>1;
if (l > mid)return Query(rt<<1|1,l,r);
if (r <= mid)return Query(rt<<1,l,r);
return Query(rt<<1,l,mid)+Query(rt<<1|1,mid+1,r);
}
int Find(int rt , int l , int r , int pos)
{
if (tree[rt].l == tree[rt].r)return tree[rt].l;
int mid = (tree[rt].l+tree[rt].r)>>1;
if (r <= mid)return Find(rt<<1,l,r,pos);
if (l > mid)return Find(rt<<1|1,l,r,pos);
int sum = Query(rt,l,mid);
if (pos <= sum)return Find(rt<<1,l,mid,pos);
return Find(rt<<1|1,mid+1,r,pos-sum);
}
void Updata(int rt , int l , int r , int val)
{
if (tree[rt].l == l && r == tree[rt].r)
{
tree[rt].fg = val;
tree[rt].sum = val*(r-l+1);
return;
}
Updata_down(rt);
int mid = (tree[rt].l+tree[rt].r)>>1;
if (r <= mid)Updata(rt<<1,l,r,val);
else if (l > mid)Updata(rt<<1|1,l,r,val);
else
{
Updata(rt<<1,l,mid,val);
Updata(rt<<1|1,mid+1,r,val);
}
tree[rt].sum = tree[rt<<1].sum+tree[rt<<1|1].sum;
}
int main()
{
int t;
scanf("%d",&t);
while (t--)
{
scanf("%d%d",&n,&m);
Build(1 , 0 , n-1);
while (m--)
{
int k , a , b;
scanf("%d%d%d",&k,&a,&b);
if (k == 1)
{
int s = Query(1,a,n-1);
if (s == 0)printf("Can not put any one.\n");
else
{
s = min(s,b);
int za = Find(1,a,n-1,1);
int yb = Find(1,a,n-1,s);
printf("%d %d\n",za,yb);
Updata(1,za,yb,0);
}
}
else
{
printf("%d\n",b-a+1-Query(1,a,b));
Updata(1,a,b,1);
}
}
printf("\n");
}
return 0;
}