Poj 3667 Hotel
Question Link
There are n rooms, and now there are two operations
1. Find an empty room with a continuous length. Try to stay on the left side. If the leftmost room number is output, if no value is output
2. Clear the [A, A + B-1] Room
Idea: Merge the intervals of the Line Segment tree, and record the consecutive longest and longest consecutive empty room on the left and the maximum value of each segment. In this way, merge the intervals during pushup, note that when querying, the left child should be checked as far as possible, so the left child should be checked first.
Code:
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define lson(x) ((x<<1)+1)#define rson(x) ((x<<1)+2)const int N = 50005;int n, m;struct Node {int l, r, lsum, rsum, sum, sumv, lazy;int size() {return r - l + 1;}void gao(int v) {lazy = v;if (v) lsum = rsum = sum = 0;else lsum = rsum = sum = r - l + 1;sumv = l;}} node[N * 4];void pushup(int x) {if (node[lson(x)].lsum == node[lson(x)].size()) node[x].lsum = node[lson(x)].lsum + node[rson(x)].lsum;else node[x].lsum = node[lson(x)].lsum;if (node[rson(x)].rsum == node[rson(x)].size()) node[x].rsum = node[lson(x)].rsum + node[rson(x)].rsum;else node[x].rsum = node[rson(x)].rsum;node[x].sum = node[lson(x)].sum;node[x].sumv = node[lson(x)].sumv;if (node[x].sum < node[lson(x)].rsum + node[rson(x)].lsum) {node[x].sum = node[lson(x)].rsum + node[rson(x)].lsum;node[x].sumv = node[lson(x)].r - node[lson(x)].rsum + 1;}if (node[x].sum < node[rson(x)].sum) {node[x].sum = node[rson(x)].sum;node[x].sumv = node[rson(x)].sumv;}}void pushdown(int x) {if (node[x].lazy != -1) {node[lson(x)].gao(node[x].lazy);node[rson(x)].gao(node[x].lazy);node[x].lazy = -1;}}void build(int l, int r, int x = 0) {node[x].l = l; node[x].r = r; node[x].lazy = -1;if (l == r) {node[x].lsum = node[x].rsum = node[x].sum = 1;return;}int mid = (l + r) / 2;build(l, mid, lson(x));build(mid + 1, r, rson(x));pushup(x);}void add(int l, int r, int v, int x = 0) {if (node[x].l >= l && node[x].r <= r) {node[x].gao(v);return;}int mid = (node[x].l + node[x].r) / 2;pushdown(x);if (l <= mid) add(l, r, v, lson(x));if (r > mid) add(l, r, v, rson(x));pushup(x);}int query(int v, int x = 0) {if (node[x].l == node[x].r) {if (node[x].sum >= v) return node[x].sumv;return 0;}pushdown(x);int ans = 0;if (node[lson(x)].sum >= v)ans = query(v, lson(x));else if (node[lson(x)].rsum + node[rson(x)].lsum >= v) ans = node[lson(x)].r - node[lson(x)].rsum + 1;else if (node[rson(x)].sum >= v)ans = query(v, rson(x));pushup(x);return ans;}int main() {while (~scanf("%d%d", &n, &m)) {build(1, n);int op, a, b;while (m--) {scanf("%d%d", &op, &a);if (op == 2) {scanf("%d", &b);add(a, a + b - 1, 0);} else {int tmp = query(a);printf("%d\n", tmp);if (tmp == 0) continue;add(tmp, tmp + a - 1, 1);}}}return 0;}
Poj 3667 Hotel (line segment tree)