线段树(区间合并) POJ 3667 Hotel
/*
题意:输入 1 a:询问是不是有连续长度为a的空房间,有的话住进最左边
输入 2 a b:将[a,a+b-1]的房间清空
线段树(区间合并):lsum[]统计从左端点起最长连续空房间数,rsum[]类似,sum[]统计区间最长连续的空房间数,
它有三种情况:1.纯粹是左端点起的房间数;2.纯粹是右端点的房间数;3.当从左(右)房间起都连续时,加上另一个子节点
从左(右)房间起的数,sum[]再求最大值更新维护。理解没错,表达能力不足
详细解释:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html
*/
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std; #define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
const int MAXN = 5e4 + 10;
const int INF = 0x3f3f3f3f;
struct Segment_Tree {
int sum[MAXN<<2], lsum[MAXN<<2], rsum[MAXN<<2], cover[MAXN<<2];
void push_up(int rt, int len) {
lsum[rt] = lsum[rt<<1];
rsum[rt] = rsum[rt<<1|1];
if (lsum[rt] == len - (len>>1)) lsum[rt] += lsum[rt<<1|1];
if (rsum[rt] == len>>1) rsum[rt] += rsum[rt<<1];
sum[rt] = max (rsum[rt<<1] + lsum[rt<<1|1], max (sum[rt<<1], sum[rt<<1|1]));
}
void push_down(int rt, int len) {
if (cover[rt] != -1) {
cover[rt<<1] = cover[rt<<1|1] = cover[rt];
sum[rt<<1] = lsum[rt<<1] = rsum[rt<<1] = cover[rt] ? 0 : len - (len>>1);
sum[rt<<1|1] = lsum[rt<<1|1] = rsum[rt<<1|1] = cover[rt] ? 0 : len >> 1;
cover[rt] = -1;
}
}
void build(int l, int r, int rt) {
sum[rt] = lsum[rt] = rsum[rt] = r - l + 1;
cover[rt] = -1;
if (l == r) return ;
int mid = (l + r) >> 1;
build (lson); build (rson);
}
void updata(int ql, int qr, int c, int l, int r, int rt) {
if (ql <= l && r <= qr) {
sum[rt] = lsum[rt] = rsum[rt] = c ? 0 : (r - l + 1);
cover[rt] = c; return ;
}
push_down (rt, r - l + 1);
int mid = (l + r) >> 1;
if (ql <= mid) updata (ql, qr, c, lson);
if (qr > mid) updata (ql, qr, c, rson);
push_up (rt, r - l + 1);
}
int query(int w, int l, int r, int rt) {
if (l == r) return l;
push_down (rt, r - l + 1);
int mid = (l + r) >> 1;
if (sum[rt<<1] >= w) return query (w, lson);
else if (rsum[rt<<1] + lsum[rt<<1|1] >= w) return mid - rsum[rt<<1] + 1;
else return query (w, rson);
}
}st; int main(void) { //POJ 3667 Hotel
int n, m;
while (scanf ("%d%d", &n, &m) == 2) {
st.build (1, n, 1);
for (int i=1; i<=m; ++i) {
int op, a, b; scanf ("%d%d", &op, &a);
if (op == 1) {
if (st.sum[1] < a) puts ("0");
else {
int p = st.query (a, 1, n, 1);
printf ("%d\n", p);
st.updata (p, p + a - 1, 1, 1, n, 1);
}
}
else {
scanf ("%d", &b);
st.updata (a, a + b - 1, 0, 1, n, 1);
}
}
} return 0;
}
线段树(区间合并) POJ 3667 Hotel的更多相关文章
- POJ 3667 Hotel(线段树 区间合并)
Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...
- Poj 3667——hotel——————【线段树区间合并】
Hotel Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 13124 Accepted: 5664 Descriptio ...
- poj3667 Hotel (线段树 区间合并)
poj3667 HotelTime Limit: 3000MS Memory Limit: 65536KTotal Submissions: 18925 Accepted: 8242Descripti ...
- 【bzoj1593】[Usaco2008 Feb]Hotel 旅馆 线段树区间合并
题目描述 奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光.作为整个旅游的策划者和负责人,贝茜选择在湖边的一家著名的旅馆住宿.这个巨大的旅馆一共有N (1 <= N & ...
- POJ 2482 Stars in Your Window (线段树区间合并+扫描线)
这题开始一直被矩形框束缚了,想法一直都是枚举线,但是这样枚举都需要O(n^2)...但是看了别人的思路,感觉这题思想真心很好(PS:开头好浪漫的描述啊,可惜并没有什么用) 题意就是在平面上给你一些星 ...
- poj-3667(线段树区间合并)
题目链接:传送门 参考文章:传送门 思路:线段树区间合并问题,每次查询到满足线段树的区间最左值,然后更新线段树. #include<iostream> #include<cstdio ...
- HDU 3911 线段树区间合并、异或取反操作
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...
- HDU 3911 Black And White(线段树区间合并+lazy操作)
开始以为是水题,结果...... 给你一些只有两种颜色的石头,0为白色,1为黑色. 然后两个操作: 1 l r 将[ l , r ]内的颜色取反 0 l r 计算[ l , r ]内最长连续黑色石头的 ...
- HYSBZ 1858 线段树 区间合并
//Accepted 14560 KB 1532 ms //线段树 区间合并 /* 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[ ...
随机推荐
- 单行bash、shell、perl命令
主题:单行经典bash.shell.perl命令 作者:luomg 摘要: 会陆陆续的写自己工作中的常用有意思的命令,争取你能看完后就能搞定常见操作, 且尽量自少提供基本shell.perl的实现方式 ...
- JSP的7个动作指令
动作指令与编译指令不同,编译指令是通知Servlet引擎的处理信息,而动作指令知识运行时的动作.编译指令在将JSP编译成Servlet时起作用,而处理指令通常可替换成JSP脚本,它知识JSP脚本的标准 ...
- [rsync]——rsync文件同步和备份
实验环境 (1) Rsync服务器:10.0.10.158 (2) Rsync客户端:10.0.10.173 Rsync服务器端的配置 1. 安装xinetd和rsync # yum install ...
- [shell基础]——read命令
read命令:在shell中主要用于读取输入.变量.文本 1. 接受标准输入(键盘)的输入,并将输入的数据赋值给设置的变量 [按回车键——表示输入完毕] [若输入的数据多于设置的变 ...
- java 参数化类型
package com.gxf.collection; import java.util.LinkedList; public class TestForT<T> { private Li ...
- 四则运算小程序测试--c++--软件工程课
一.测试内容: 1.生成题目数是否准确?2.打印方式(列数l.行间距jj)是否准确?3.有无乘除法cc是否准确?4.数的范围fw是否准确?5.除法有无余数c是否准确?6.加减有无负数f是否准确? 二. ...
- 30道小学生四则运算题C/C++编程
软件工程科课上,老师通过实例讲解什么是程序,程序和软件的区别,要求我们通过短时间写一道编程题, 题目就是编写30道小学生四则运算题.以下就是源代码: #include<iostream.h> ...
- c语言编程之双向循环链表
双向循环链表就是形成两个环,注意每个环的首尾相连基本就可以了. 程序中采用尾插法进行添加节点. #include<stdio.h> #include<stdlib.h> #de ...
- 国内最快的jquery cdn
cdnjs.cn是cdnjs.com在国内的镜像服务,项目托管与著名的又拍云存储,目前又拍云在全国有几十个cdn节点,并且还在增加中. cdnjs.cn 托管的jquery相信会成为国内最快的jque ...
- JavaScript DOM动态创建(声明)Object元素
http://www.cnblogs.com/GuominQiu/archive/2011/04/01/2002783.html 一文提及“等整个页面加载完毕后,根据用户所选的阅读机类型,再用Java ...