hdu 4614 Vases and Flowers
Posted rosebud
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 ", 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 ", x, y); update(x, y, 0, 0, N - 1, 1); } } puts(""); } return 0; }
以上是关于hdu 4614 Vases and Flowers的主要内容,如果未能解决你的问题,请参考以下文章
HDU 4614 Vases and Flowers 线段树+二分
HDU4614Vases and Flowers 二分+线段树;