题目链接:http://poj.org/problem?id=3667
题目大意:给n个房间,m次操作,2种操作,1是找到最左边的连续d个空房间入住返回开头房间的位置,2从x开始的d个房间变成空房间。
代码
#include <iostream> #include <string> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #include <queue> #include <functional> #include <map> #include <set> #include <stack> #define FT(a, b) memset(a, b, sizeof(a)) #define FAT(a) memset(a, 0, sizeof(a)) using namespace std; typedef long long ll; const int M = 5e4 + 10; const int INF = 0x3f3f3f3f; struct node { int l, r, msum, lsum, rsum, lazy; } tree[M * 4]; int n, m; void push_up(int root) { node &l = tree[root << 1], &r = tree[root << 1 | 1], &u = tree[root]; u.msum = max(max(l.msum, r.msum), l.rsum + r.lsum); u.lsum = l.lsum; u.rsum = r.rsum; if (l.lsum == l.r - l.l + 1) u.lsum += r.lsum; if (r.rsum == r.r - r.l + 1) u.rsum += l.rsum; } void build(int root, int l, int r) { tree[root] = {l, r, r - l + 1, r - l + 1, r - l + 1, -1}; if (l != r) { int mid = l + r >> 1; build(root << 1, l, mid); build(root << 1 | 1, mid + 1, r); } } void push_down(int root) { node &l = tree[root << 1], &r = tree[root << 1 | 1], &u = tree[root]; if (u.lazy == -1) return; l.lazy = r.lazy = u.lazy; if (u.lazy == 0) l.lsum = l.msum = l.rsum = r.lsum = r.msum = r.rsum = 0; else l.lsum = l.msum = l.rsum = (l.r - l.l + 1), r.lsum = r.msum = r.rsum = (r.r - r.l + 1); u.lazy = -1; } void modify(int root, int l, int r, int c) { if (tree[root].l >= l && tree[root].r <= r) { if (c == 0) tree[root].lsum = tree[root].msum = tree[root].rsum = 0; else tree[root].lsum = tree[root].msum = tree[root].rsum = (tree[root].r - tree[root].l + 1); tree[root].lazy = c; } else { push_down(root); int mid = tree[root].l + tree[root].r >> 1; if (l <= mid) modify(root << 1, l, r, c); if (r > mid) modify(root << 1 | 1, l, r, c); push_up(root); } } int add(int root, int d) { if (tree[root << 1].lsum >= d) { modify(1, tree[root << 1].l, tree[root << 1].l + d - 1, 0); return tree[root << 1].l; } else if (tree[root << 1].msum >= d) return add(root << 1, d); else if (tree[root << 1].rsum + tree[root << 1 | 1].lsum >= d) { int L = tree[root << 1].r - tree[root << 1].rsum + 1; modify(1, L, L + d - 1, 0); return L; } else if (tree[root << 1 | 1].msum >= d) return add(root << 1 | 1, d); else return 0; } int main() { #ifdef ONLINE_JUDGE #else freopen("D:\\code\\c++\\in.txt", "r", stdin); #endif scanf("%d%d", &n, &m); build(1, 1, n); while (m--) { int a; scanf("%d", &a); if (a == 1) { int d; scanf("%d", &d); printf("%d\n", add(1, d)); } else { int x, y; scanf("%d%d", &x, &y); modify(1, x, x + y - 1, 1); } } return 0; }