【CodeForce】 46D Parking Lot (线段树 区间合并)
2015-03-07 15:38
501 查看
题目大意:有一条长度为L的街道,有N个操作,操作有两种,(1)"1 a",表示有一辆长度为a的车开进来想找停车位,停车位必须满足与它前面的车距离至少为b,与后面的车距离至少为f.如果能找到这样的停车位,输出这辆车的起始位置(且这个位置最小),否则输出-1。(2)"2 a",表示第a个事件里进来停车的那辆车开出去了
思路:需要分4种情况
1、没有前面和没有后面,也就是正好这个车的长度等于停车场的长度
2、只有后面,这个情况是指车正好放在0的位置。
3、只有前面,这个情况是指车放在最后面的地方
4、都有的情况。
思路:需要分4种情况
1、没有前面和没有后面,也就是正好这个车的长度等于停车场的长度
2、只有后面,这个情况是指车正好放在0的位置。
3、只有前面,这个情况是指车放在最后面的地方
4、都有的情况。
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; #define MAX 100010 #define ls rt<<1 #define rs ls|1 #define m (l+r)>>1 int sum[MAX << 2]; int lsum[MAX << 2]; int rsum[MAX << 2]; int col[MAX << 2]; struct { int s, e; }car[MAX]; void uprt(int len, int rt) { lsum[rt] = lsum[ls]; rsum[rt] = rsum[rs]; if (lsum[rt] == len - (len >> 1)) lsum[rt] += lsum[rs]; if (rsum[rt] == (len >> 1)) rsum[rt] += rsum[ls]; sum[rt] = max(rsum[ls] + lsum[rs], max(sum[ls], sum[rs])); } void ups(int len, int rt) { if (col[rt] != -1) { if (col[rt] == 0) { lsum[ls] = rsum[ls] = sum[ls] = 0; lsum[rs] = rsum[rs] = sum[rs] = 0; } else { lsum[rs] = rsum[rs] = sum[rs] = (len >> 1); lsum[ls] = rsum[ls] = sum[ls] = len - (len >> 1); } col[ls] = col[rs] = col[rt]; col[rt] = -1; } } void updata(int L, int R, int c, int l, int r, int rt) { int len = r - l + 1; if (L <= l&&r <= R) { col[rt] = c; if (c == 0) lsum[rt] = rsum[rt] = sum[rt] = 0; else lsum[rt] = rsum[rt] = sum[rt] = len; return; } ups(len, rt); int mid = m; if (L <= mid) updata(L, R, c, l, mid, ls); if (mid < R) updata(L, R, c, mid + 1, r, rs); uprt(len, rt); } int query(int len, int l, int r, int rt) { if (l == r) return l; int mid=m; ups(r - l + 1, rt); if (sum[ls] >= len) return query(len, l, mid, ls); if (rsum[ls] + lsum[rs] >= len) return mid - rsum[ls] + 1; return query(len, mid + 1, r, rs); } void build(int l, int r, int rt) { if (l == r) { lsum[rt] = rsum[rt] = sum[rt] = 1; return; } int mid = m; build(l, mid, ls); build(mid + 1, r, rs); uprt(r - l + 1, rt); } int main() { int n, b, f; scanf("%d%d%d", &n, &b, &f); memset(col, -1, sizeof(col)); n--; build(0, n, 1); int t; cin >> t; int x, y; int pos; int pos2; bool posx=0; int k = b + f; int cnt = 0; while (t--) { cnt++; scanf("%d%d", &x, &y); if (x == 1) { pos = -1; if (y == n + 1 && y == sum[1]) { car[cnt].s = 0; car[cnt].e = n; updata(0, n, 0, 0, n, 1); puts("0"); continue; } if (lsum[1] >= y + f) { pos = 0; updata(0, y - 1, 0, 0, n, 1); car[cnt].s = 0; car[cnt].e = y - 1; } else if (sum[1] >= y + k) { pos = query(y + k, 0, n, 1); pos += b; updata(pos, pos + y - 1, 0, 0, n, 1); car[cnt].s = pos; car[cnt].e = pos + y - 1; } else if (rsum[1] >= y + b) { pos = n - rsum[1] + b+1; updata(pos, pos + y - 1, 0, 0, n, 1); car[cnt].s = pos; car[cnt].e = pos + y - 1; } printf("%d\n", pos); } else { updata(car[y].s, car[y].e, 1, 0, n, 1); if (car[y].s == 0) posx = 0; } } }
相关文章推荐
- codeforces 46D Parking Lot(线段树 区间合并)
- CodeForces 46D Parking Lot(线段树区间合并)
- CodeForces 46D Parking Lot (线段树区间合并)
- 喵哈哈村的冒菜店(线段树 区间合并)
- 线段树区间合并模板-杭电1540
- 【bzoj2325】[ZJOI2011]道馆之战 树链剖分+线段树区间合并
- hud 4718 The LCIS on the Tree(树链剖分+线段树区间合并)
- POJ 3667 线段树的区间合并简单问题
- uestc 1425 线段树 区间合并
- POJ 3667 Hotel(线段树 区间合并 模板题)
- hdu 1540 Tunnel Warfare 【线段树 区间合并】
- hdoj 3397 Sequence operation 【线段树区间覆盖 + 异或 + 合并】【维护延迟标记的顺序】
- hdu--1540 Tunnel Warfare(线段树+区间合并)
- POJ3667:Hotel(线段树区间合并)
- HDU2871:Memory Control(线段树区间合并)
- hdu 1199 Color the Ball (线段树区间合并,离散化)
- poj 3468(线段树区间修改合并)
- POJ 3667 Hotel(线段树区间合并)
- poj3667 Hotel 线段树 区间合并
- poj 3667 Hotel(线段树,成段更新,区间合并,Lazy思想)