思路:
将该花盆中无花看成1,有花看成0,因为叶子结点只有0/1两种情况,直接修改节点值即可,
操作1:
因为l ~ n-1区间中,r为区间中的点,l~r区间值递增,所以可以二分+Query函数,
找到以输入l为起点区间值为1的st点,和st起点区间值为num的ed点,再更新即可。
操作2:
区查区改即可。
代码:
#include <bits/stdc++.h>
#define fastio ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL)
#define debug(a) cout << "debug : " << (#a) << " = " << a << endl
#define lson idx << 1
#define rson idx << 1 | 1
using namespace std;
typedef long long ll;
typedef pair<ll, ll> PII;
const int N = 5e4 + 10;
const int INF = 0x3f3f3f3f;
const double eps = 1e-6;
const int mod = 998244353;
int n, m, st, num, ed;
struct node
{
int l, r;
ll w;
} tree[N << 2];
int lazy[N << 2];
inline void PushUp(int idx)
{
tree[idx].w = tree[lson].w + tree[rson].w;
}
inline void PushDown(int idx)
{
if (lazy[idx] != -1)
{
lazy[lson] = lazy[idx];
lazy[rson] = lazy[idx];
int mid = (tree[idx].l + tree[idx].r) >> 1;
tree[lson].w = lazy[idx] * (mid - tree[idx].l + 1);
tree[rson].w = lazy[idx] * (tree[idx].r - mid);
lazy[idx] = -1;
}
}
void Build(int idx, int l, int r)
{
lazy[idx] = -1;
tree[idx].l = l;
tree[idx].r = r;
if (l == r)
{
tree[idx].w = 1;
return;
}
int mid = l + r >> 1;
Build(lson, l, mid);
Build(rson, mid + 1, r);
PushUp(idx);
}
inline void Update(int idx, int l, int r, int k)
{
if (tree[idx].l >= l && tree[idx].r <= r)
{
tree[idx].w = k * (tree[idx].r - tree[idx].l + 1);
lazy[idx] = k;
return;
}
PushDown(idx);
if (tree[lson].r >= l)
Update(lson, l, r, k);
if (tree[rson].l <= r)
Update(rson, l, r, k);
PushUp(idx);
}
inline ll Query(int idx, int l, int r)
{
if (tree[idx].l >= l && tree[idx].r <= r)
return tree[idx].w;
PushDown(idx);
ll sum = 0;
if (tree[lson].r >= l)
sum += Query(lson, l, r);
if (tree[rson].l <= r)
sum += Query(rson, l, r);
return sum;
}
inline int Binary_Search(int st, int ed, int k)
{
int l = st, r = ed;
while (l < r)
{
int mid = l + r >> 1;
ll t = Query(1, st, mid);
if (t < k)
l = mid + 1;
else
r = mid;
}
return l;
}
int main()
{
int T;
cin >> T;
for (int i = 1; i <= T; i++)
{
scanf("%d%d", &n, &m);
Build(1, 0, n - 1);
for (int j = 1; j <= m; j++)
{
int op, l, r;
scanf("%d%d", &op, &l);
if (op == 1)
{
scanf("%d", &num);
int t = Query(1, l, n - 1);
if (t == 0)
printf("%s\n", "Can not put any one.");
else
{
l = Binary_Search(l, n - 1, 1);
r = Binary_Search(l, n - 1, min(num, t));
printf("%d %d\n", l, r), Update(1, l, r, 0);
}
}
else if (op == 2)
{
scanf("%d", &r);
ll t = r - l + 1 - Query(1, l, r);
printf("%lld\n", t);
Update(1, l, r, 1);
}
}
printf("\n");
}
return 0;
}