codeforces 46D Parking Lot(线段树模拟区间管理 or set模拟)
2015-08-28 01:47
337 查看
题意:
可以看成是 poj Hotel 那道题的加强版。
这里是找车位,还要考虑与前后车之间的距离。。
不过这里n只有100,用set,就成了水题啊。。。
思路:
1) 线段树
比起 Hotel 也就是多讨论几种情况吧。。
2)set模拟
set 维护车占的区间前后端点。
有个小技巧, 虚拟一个 -b 和 L + f 端点,情况就统一了。。
可以看成是 poj Hotel 那道题的加强版。
这里是找车位,还要考虑与前后车之间的距离。。
不过这里n只有100,用set,就成了水题啊。。。
思路:
1) 线段树
比起 Hotel 也就是多讨论几种情况吧。。
const int N = 100000 + 5; struct Node { int len, l, r, m, tag; // 0 - no tag, 1 - free, 2 - occupied void upd(int x) { if ( x == 1 ) { l = r = m = len; } if ( x == 2 ) { l = r = m = 0; } tag = x; } }; Node tr[N<<2]; int qL, qR; #define lc o<<1 #define rc o<<1|1 void push_down(int o) { if ( tr[o].tag ) { tr[lc].upd(tr[o].tag); tr[rc].upd(tr[o].tag); tr[o].tag = 0; } } void push_up(int o) { tr[o].l = tr[lc].l; if ( tr[lc].l == tr[lc].len ) tr[o].l += tr[rc].l; tr[o].r = tr[rc].r; if ( tr[rc].r == tr[rc].len ) tr[o].r += tr[lc].r; tr[o].m = tr[lc].r + tr[rc].l; tr[o].m = max ( tr[o].m, max ( tr[lc].m, tr[rc].m ) ); } int query(int o, int l, int r) { if ( tr[o].m < qL ) return -1; if ( l == r ) return l; // take care... int m = (l + r) >> 1, ret; push_down(o); if ( tr[lc].m >= qL ) ret = query(lc, l, m); else if ( tr[lc].r + tr[rc].l >= qL ) { ret = m - tr[lc].r + 1; } else { ret = query(rc, m+1, r); } push_up(o); return ret; } void update(int o, int l, int r, int x) { if ( qL <= l && r <= qR ) { tr[o].upd(x); //cout << " upd: " << l << ' ' << r << " : " << tr[o].l << ' ' << tr[o].r << ' ' << tr[o].m << endl; return; } int m = (l + r) >> 1; push_down(o); if ( qL <= m ) update(lc, l, m, x); if ( qR > m ) update(rc, m+1, r, x); push_up(o); //cout << " upd: " << l << ' ' << r << " : " << tr[o].l << ' ' << tr[o].r << ' ' << tr[o].m << endl; } void build(int o, int l, int r) { int len = r - l + 1; tr[o] = (Node) {len, len, len, len, 0}; if ( l != r ) { int m = (l + r) >> 1; build(lc, l, m); build(rc, m+1, r); } } int rec [2], L, b, f, n; int search_space(int i, int car) { int id; if ( tr[1].m == L ) { // no car qL = car; id = query(1, 1, L); if ( id != -1 ) { rec[i][0] = id, rec[i][1] = id + car - 1; return id - 1; } } qL = car + f; if ( tr[1].l >= qL ) { id = 1; rec[i][0] = id, rec[i][1] = id + car - 1; return id - 1; } qL = car + b + f; id = query(1, 1, L); if ( id != -1 ) { id += b; rec[i][0] = id, rec[i][1] = id + car - 1; return id - 1; } qL = car + b; if ( tr[1].r >= qL ) { id = L - tr[1].r + b + 1; rec[i][0] = id, rec[i][1] = id + car - 1; return id - 1; } return -1; } int main() { #ifdef _LOCA_ENV_ freopen("input.in", "r", stdin); #endif // _LOCA_ENV int x, y; scanf("%d%d%d%d", &L, &b, &f, &n); memset(rec, -1, sizeof(rec)); build(1, 1, L); rep(i, 1, n) { scanf("%d%d", &x, &y); if ( x == 1 ) { int res = search_space(i, y); if ( res != -1 ) { qL = rec[i][0], qR = rec[i][1]; update(1, 1, L, 2); } printf("%d\n", res); } else { qL = rec[y][0], qR = rec[y][1]; update(1, 1, L, 1); } } return 0; }
2)set模拟
set 维护车占的区间前后端点。
有个小技巧, 虚拟一个 -b 和 L + f 端点,情况就统一了。。
const int N = 100000 + 5; int rec [2], L, b, f, n; set<int> s; set<int>::iterator fir, sec; int search_space(int i, int car) { int len = car + b + f; for(fir = s.begin(); fir != s.end(); ++ fir) { sec = fir; ++ sec; if ( sec != s.end() && *sec - *fir >= len ) { int st = *fir + b; int ed = st + car; s.insert(st); s.insert(ed); rec[i][0] = st; rec[i][1] = ed; return st; } ++ fir; } return -1; } int main() { #ifdef _LOCA_ENV_ freopen("input.in", "r", stdin); #endif // _LOCA_ENV int x, y; scanf("%d%d%d%d", &L, &b, &f, &n); memset(rec, -1, sizeof(rec)); s.insert(-b); s.insert(L + f); rep(i, 1, n) { scanf("%d%d", &x, &y); if ( x == 1 ) { int res = search_space(i, y); printf("%d\n", res); } else { s.erase(rec[y][0]); s.erase(rec[y][1]); } } return 0; }
相关文章推荐
- Redis主从配置详细过程
- HDU 5002 Tree (2014年鞍山赛区网络赛F题)
- 一步一步学习SignalR进行实时通信_4_Hub
- 例题3.13 周期 LA3026
- 递归算法(一)——akm
- poj 3187 Backward Digit Sums(穷竭搜索dfs)
- 算法题:二分查找的溢出考虑
- iOS中的动画二
- zoj 3362 Beer Problem 【最大费用最大流 需要判断最长路值是否为负】
- 使用EmguCv计算包围物体的最小圆与最小可旋转矩形和不可选择矩形
- 总结的一些css3的一些东西,放个地方吧
- 在 Parallels Desktop 中,全屏模式使用 Win7,唤醒时黑屏
- IOS动画Core Animation详解
- 在 Parallels Desktop 中,全屏模式使用 Win7,唤醒时黑屏
- 使用uiautomator的python封装进行android的UI测试
- ZOJ1745 解题报告
- ubuntu安装tushare
- ISO/IEC 9899:2011 条款6.3.2——其它操作数
- Linux磁盘管理--LVM原理及基本操作
- Qt On Android开发环境安装、配置