题目传送门

/*
题意:输入 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的更多相关文章

  1. POJ 3667 Hotel(线段树 区间合并)

    Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...

  2. Poj 3667——hotel——————【线段树区间合并】

    Hotel Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 13124   Accepted: 5664 Descriptio ...

  3. poj3667 Hotel (线段树 区间合并)

    poj3667 HotelTime Limit: 3000MS Memory Limit: 65536KTotal Submissions: 18925 Accepted: 8242Descripti ...

  4. 【bzoj1593】[Usaco2008 Feb]Hotel 旅馆 线段树区间合并

    题目描述 奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光.作为整个旅游的策划者和负责人,贝茜选择在湖边的一家著名的旅馆住宿.这个巨大的旅馆一共有N (1 <= N & ...

  5. POJ 2482 Stars in Your Window (线段树区间合并+扫描线)

    这题开始一直被矩形框束缚了,想法一直都是枚举线,但是这样枚举都需要O(n^2)...但是看了别人的思路,感觉这题思想真心很好(PS:开头好浪漫的描述啊,可惜并没有什么用)  题意就是在平面上给你一些星 ...

  6. poj-3667(线段树区间合并)

    题目链接:传送门 参考文章:传送门 思路:线段树区间合并问题,每次查询到满足线段树的区间最左值,然后更新线段树. #include<iostream> #include<cstdio ...

  7. HDU 3911 线段树区间合并、异或取反操作

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...

  8. HDU 3911 Black And White(线段树区间合并+lazy操作)

    开始以为是水题,结果...... 给你一些只有两种颜色的石头,0为白色,1为黑色. 然后两个操作: 1 l r 将[ l , r ]内的颜色取反 0 l r 计算[ l , r ]内最长连续黑色石头的 ...

  9. HYSBZ 1858 线段树 区间合并

    //Accepted 14560 KB 1532 ms //线段树 区间合并 /* 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[ ...

随机推荐

  1. OSGi之Bundle

    OSGi提出的根源是什么?在我看来就是对JVM的类加载机制进行了扩展,添加了一系列的规则,使得原有的类包(Class Package)扩展到类域(Class Domain).然后是建立在类域上的一系列 ...

  2. iOS进阶学习-CoreData

    一.CoreData数据库框架的优势 1.CoreData数据持久化框架是Cocoa API的一部分,首次在iOS5版本的系统中出现,它允许按照实体-属性-值模型组织数据,并以XML.二进制文件或者S ...

  3. NSKeyValueObserving(KVO)

    NSKeyValueObserving非正式协议定义了一种机制,它允许对象去监听其它对象的某个属性的修改. 我们可以监听一个对象的属性,包括简单属性,一对一的关系,和一对多的关系.一对多关系的监听者会 ...

  4. 新手学Android

    Eclipse平台下的新手Android学习记录. 1.打开一个本地的项目 在Project Explorer右键->Import->Existing Projects into Work ...

  5. shell操作文件的几条命令:删除最后一列、删除第一行、diff等

    删除文件第一行: sed '1d' filename 删除文件最后一列: awk '{print $NF}' filename awk删除重复行的命令:awk '{if (!seen[$0]++) { ...

  6. UISegmentedControl swift

    // // ViewController.swift // UILabelTest // // Created by mac on 15/6/23. // Copyright (c) 2015年 fa ...

  7. [shell基础]——find命令

    find命令选项 -name 按照文件名查找 -type 查找某一类型的文件(b 代表设备块:d 目录:c 字符设备文件:l 符号(软)链接文件:f 普通文件) -size 查找文件长度或者大小 -p ...

  8. 收集的冻结table 标题和左侧(完美)

     <html> <head>     <meta name="viewport" content="width=device-width&q ...

  9. Implementation Documentation[转]

    原文地址:http://prasanna-adf.blogspot.tw/2009/04/implementation-documentation.html Following are the lis ...

  10. Careercup - Google面试题 - 5634470967246848

    2014-05-06 07:11 题目链接 原题: Find a shortest path ,) to (N,N), assume is destination, use memorization ...