hdu 4614 Vases and Flowers
题目大意:有编号为[0,N-1]的花盆,有下述2种操作:
1 A F,有F朵花,从A开始放入花盆,(最后放不下的丢弃)
2 A B,清理[A,B]花盆里的花。
对每种操作:对1输出第一个和最后一个放入花的花盆编号,无位置时输出“Can not put any one.”
对2输出清理掉的花盆数量。
对2操作,就是一个简单的线段树区间和的查询,不提先。
对于1操作,相当要找到[A, N-1]花盆中第k个空盆。一开始想的时候,线段树结点T[rt]表示的是这个区间花的数量,这样来求第k个空盆比较麻烦,后面转成想:T[rt]表示的是这个区间空盆数量,再找的时候就如同query2写的,非常流畅了。另:第k个空盆,这个k得在剩余空盆和实际要插的花朵数量之间取min。
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
#define ll long long
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define DOR(i,a,b) for(int i=(a);i>=(b);--i)
const int maxN=5e4+5,inf=0x3f3f3f3f;
int N, M, K, T[maxN<<2], Z[maxN<<2];
#define lson l,m,rt*2
#define rson m+1,r,rt*2+1
void push_up(int rt) {T[rt] = T[rt * 2] + T[rt * 2 + 1];}
void push_down(int l, int r, int rt) {
if (Z[rt] == -1) return;
int lch = rt * 2, rch = lch + 1;
Z[lch] = Z[rch] = Z[rt];
int LE = r - l + 1;
T[lch] = (LE - LE / 2) * Z[rt];
T[rch] = (LE / 2) * Z[rt];
Z[rt] = -1;
}
void build(int l, int r, int rt) {
Z[rt] = -1;
T[rt] = (r - l + 1);
if (l == r) return;
int m = (l + r) / 2;
build(lson), build(rson);
push_up(rt);
}
void update(int L, int R, int x, int l, int r, int rt) {
if (L <= l && r <= R) {
Z[rt] = x;
T[rt] = (r - l + 1) * x;
return;
}
push_down(l, r, rt);
int m = (l + r) / 2;
if (L <= m) update(L, R, x, lson);
if (R > m) update(L, R, x, rson);
push_up(rt);
}
int query1(int L, int R, int l, int r, int rt) {
if (L <= l && r <= R) return T[rt];
push_down(l, r, rt);
int m = (l + r) / 2;
int ans = 0;
if (L <= m) ans += query1(L, R, lson);
if (R > m) ans += query1(L, R, rson);
// push_up(rt);
return ans;
}
int query2(int L, int R, int k, int l, int r, int rt) {
if (l == r) return l;
push_down(l, r, rt);
int m = (l + r) / 2;
int cnt = query1(L, m, l, r, rt);
if (cnt >= k) return query2(L, R, k, lson);
else return query2(L, R, k - cnt, rson);
}
int main () {
int cas;
scanf("%d", &cas);
FOR(ca, 1, cas) {
scanf("%d%d", &N, &M);
build(0, N - 1, 1);
int op, a, b;
FOR(j, 1, M) {
scanf("%d%d%d", &op, &a, &b);
if (op == 2) {
int q = query1(a, b, 0, N - 1, 1);
printf("%d\n", b - a + 1 - q);
update(a, b, 1, 0, N - 1, 1);
} else {
if (query1(a, N - 1, 0, N - 1, 1) == 0) {
puts("Can not put any one.");
continue;
}
int empty = query1(a, N - 1, 0, N - 1, 1);
int x = query2(a, N - 1, 1, 0, N - 1, 1);
int y = query2(a, N - 1, min(b, empty), 0, N - 1, 1);
printf("%d %d\n", x, y);
update(x, y, 0, 0, N - 1, 1);
}
}
puts("");
}
return 0;
}