【随便做做|线段树】POJ3667 Hotel
来源:互联网 发布:淘宝买家可以延长收货 编辑:程序博客网 时间:2024/06/06 13:00
- 题意:
1→n 的房间,初始为空。有两种操作:- 操作
1 : 需要选出连续一段的若干个房间入住,输出起点位置,选不出则输出0 。 - 操作
2 : 将从left 开始的连续size 个房间清空。 - 数据规模:
n,m≤50000
- 操作
- 题解:用线段树|区间树维护。节点主要维护三个值
:{ml,mr,md} ,分别表示从左端开始连续,从右端开始向左连续,整段区间连续的最长子区段的长度。对第一种操作,只需要无脑query ,然后对query 到的结果([from,to] )进行更新即可;对第二种操作,当然就和上述更新差不多辣~ - P.S. 为了保证按照上述方法维护时线段树的单次操作复杂度,需要加入
lazy 操作,呃。。。胡乱地搞一下,就可以通过了。。。
/* ********************************************** File Name: 3667.cpp Auther: zhengdongjian@tju.edu.cn Created Time: 2015/9/22 星期二 下午 9:16:53*********************************************** */#include <map>#include <set>#include <list>#include <cmath>#include <ctime>#include <deque>#include <queue>#include <stack>#include <bitset>#include <cstdio>#include <string>#include <vector>#include <climits>#include <complex>#include <cstdlib>#include <cstring>#include <fstream>#include <sstream>#include <utility>#include <iostream>#include <algorithm>#include <functional>using namespace std;typedef long long ll;typedef pair<int, int> P;const int MAX = 50007;struct Node { int ml; int mr; int md; int lazy;} room[MAX << 2];void build(int root, int left, int right) { room[root].ml = room[root].mr = room[root].md = right - left + 1; room[root].lazy = 0; if (left == right) { return; } int mid = (left + right) >> 1; build(root << 1, left, mid); build(root << 1 | 1, mid + 1, right);}void pushup(int root, int left, int right) { int ls = root << 1; int rs = root << 1 | 1; int mid = (left + right) >> 1; room[root].ml = room[ls].ml; if (room[ls].ml == mid - left + 1) { room[root].ml += room[rs].ml; } room[root].mr = room[rs].mr; if (room[rs].mr == right - mid) { room[root].mr += room[ls].mr; } room[root].md = max(max(room[ls].md, room[rs].md), max(room[root].ml, room[root].mr)); if (room[ls].mr + room[rs].ml > room[root].md) { room[root].md = room[ls].mr + room[rs].ml; }}void pushdown(int root, int left, int right) { //printf("pushdown (%d, %d)\n", left, right); if (left == right) { room[root].ml = room[root].mr = room[root].md = (~room[root].lazy) ? 0 : 1; room[root].lazy = 0; return; } room[root << 1].lazy = room[root << 1 | 1].lazy = room[root].lazy; if (~room[root].lazy) { room[root << 1].ml = room[root << 1].mr = room[root << 1].md = 0; room[root << 1 | 1].ml = room[root << 1 | 1].mr = room[root << 1 | 1].md = 0; } else { int mid = (left + right) >> 1; room[root << 1].ml = room[root << 1].mr = room[root << 1].md = mid - left + 1; room[root << 1 | 1].ml = room[root << 1 | 1].mr = room[root << 1 | 1].md = right - mid; } room[root].lazy = 0;}void check_out(int root, int left, int right, int from, int to) { //printf("check out (%d, %d) with %d, %d...", left, right, from, to); if (to < left || from > right) { //puts("not match"); return; } else if (from <= left && to >= right) { //puts("all match"); room[root].ml = room[root].mr = room[root].md = right - left + 1; //all clear room[root].lazy = -1; return; } //puts("match some"); if (room[root].lazy != 0) { pushdown(root, left, right); } int mid = (left + right) >> 1; check_out(root << 1, left, mid, from, to); check_out(root << 1 | 1, mid + 1, right, from, to); pushup(root, left, right);}int query(int root, int left, int right, int cnt) { //printf("query %d, %d, %d (%d, %d, %d)...", left, right, cnt, room[root].ml, room[root].mr, room[root].md); if (room[root].md < cnt) { //printf("(%d, %d, %d) not enough!\n", room[root].ml, room[root].mr, room[root].md); return 0; } if (left == right) { //printf("equal to one\n"); return left; } //puts("to judge:"); if (room[root].lazy != 0) { pushdown(root, left, right); } int mid = (left + right) >> 1; int le = query(root << 1, left, mid, cnt); if (le > 0) { //printf("get left\n"); return le; } if (room[root << 1].mr + room[root << 1 | 1].ml >= cnt) { //printf("get mid\n"); return mid - room[root << 1].mr + 1; } //printf("get right\n"); return query(root << 1 | 1, mid + 1, right, cnt);}void check_in(int root, int left, int right, int from, int to) { //printf("check in %d, %d, with %d, %d...", left, right, from, to); if (to < left || from > right) { //printf("match failed!\n"); return; } else if (from <= left && to >= right) { //puts("match all!"); room[root].lazy = 1; room[root].ml = room[root].mr = room[root].md = 0; return; } //puts("match some"); if (room[root].lazy) { pushdown(root, left, right); } int mid = (left + right) >> 1; check_in(root << 1, left, mid, from, to); check_in(root << 1 | 1, mid + 1, right, from, to); pushup(root, left, right); //printf("and update (%d, %d) to %d, %d, %d\n", left, right, room[root].ml, room[root].mr, room[root].md);}void debug(int root, int left, int right) { printf("(%d, %d) => (%d, %d, %d, %d)\n", left, right, room[root].ml, room[root].mr, room[root].md, room[root].lazy); if (left == right) { return; } int mid = (left + right) >> 1; debug(root << 1, left, mid); debug(root << 1 | 1, mid + 1, right);}int main() { int n, m; while (~scanf(" %d %d", &n, &m)) { build(1, 1, n); int op, sz, le; while (m--) { scanf(" %d", &op); if (op == 1) { scanf(" %d", &sz); le = query(1, 1, n, sz); //printf("le = %d\n", le); if (le) check_in(1, 1, n, le, le + sz - 1); printf("%d\n", le); } else { scanf(" %d %d", &le, &sz); check_out(1, 1, n, le, le + sz - 1); } //debug(1, 1, n); } } return 0;}
0 0
- 【随便做做|线段树】POJ3667 Hotel
- 【poj3667】【线段树】Hotel
- 【线段树】Hotel POJ3667
- POJ3667 Hotel(线段树)
- 线段树 poj3667 Hotel
- 【POJ3667】Hotel-线段树
- #POJ3667#Hotel(线段树)
- poj3667 Hotel(线段树)
- 线段树典型例题--poj3667 hotel
- POJ3667——Hotel(线段树)
- poj3667 Hotel (线段树区间合并)
- POJ3667:Hotel(线段树区间合并)
- poj3667 Hotel 线段树 区间合并
- POJ3667-Hotel-线段树区间合并(模板)
- poj3667-Hotel 线段树区间合并
- poj3667 Hotel (线段树+区间合并)
- poj3667 Hotel (线段树--区间合并)转自网络
- poj3667 Hotel 线段树延迟更新 区间合并
- git and eclipse
- Hadoop2.6+jdk8的安装部署(1)——使用jar包安装部署【详细】
- 格雷码的实现
- Eclipse 添加 Python 主题
- HDU - 2639 Bone Collector II(第K大01背包)
- 【随便做做|线段树】POJ3667 Hotel
- Python之列表推导式
- 2015北京网络赛 G题 Boxes bfs
- java 面对象的思想
- csdn 使用live writer
- 洛谷9月noip模拟赛
- ubuntu 环境下编译 hadoop 2.6.0的简单方法
- 黑马程序员----C 语言学习笔记之程序的结构及分类
- Servlet事件监听器