• 题意:1→n1\to n的房间,初始为空。有两种操作:

    • 操作11: 需要选出连续一段的若干个房间入住,输出起点位置,选不出则输出00。
    • 操作22: 将从leftleft开始的连续sizesize个房间清空。
    • 数据规模: n,m≤50000n,m\le 50000
  • 题解:用线段树|区间树维护。节点主要维护三个值:{ml,mr,md}:\{ml,mr,md\},分别表示从左端开始连续,从右端开始向左连续,整段区间连续的最长子区段的长度。对第一种操作,只需要无脑queryquery,然后对queryquery到的结果([from,to][from,to])进行更新即可;对第二种操作,当然就和上述更新差不多辣~
  • P.S. 为了保证按照上述方法维护时线段树的单次操作复杂度,需要加入lazylazy操作,呃。。。胡乱地搞一下,就可以通过了。。。
/* **********************************************File Name: 3667.cppAuther: zhengdongjian@tju.edu.cnCreated 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 clearroom[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;
}

【随便做做|线段树】POJ3667 Hotel相关推荐

  1. 和Leo一起做爱线段树的好孩子HDU5238 Calculator

    额 神仙题 感觉就是一个暴力啊 线段树维护的是一个类似于键值线段树的东西? 每个叶子节点才表示一个操作 而在PushUp的时候合并答案 这个咋合并? 暴力合并.我们记录下当前模意义下所有的答案 然后暴 ...

  2. 和Leo一起做爱线段树的好孩子之火车运输

    ByteLand火车站(编号0)每天都要发往全国各地N列客运火车,编号1 N.第i列火车的目的地是编号Si的火车站. 对任意车站X,都与X+1车站有铁轨直接相连,因此火车站可以看成数轴上的整数点,第i ...

  3. 线段树学习心得 poj3468

    2016.5.10 神奇的博主回来了 今天,当然讲的就是加强版的堆,其实算线段树的说... (还有你们看过的留留言好不好呀,谢谢了) --------------------------- 今天说的就 ...

  4. poj 2352 Stars 线段树(先建后查/边建边查)/树状数组三种方法思路详解,带你深入了解线段树难度⭐⭐⭐★

    poj 2352 Stars 目录 poj 2352 Stars 1.树状数组 2.线段树,先建树后查找 3.线段树,边建树边查找 Description Astronomers often exam ...

  5. Master of GCD(差分数组||线段树)

    题意:长度为n的数组,一开始都是1.对于区间操作l,r,x,在l~r上乘以x.x2||x3.问操作完毕之后,n个数的最大公因子是多少. 对于每个x,都等于2或者是3.那么看最大的公因子,就看各个位置上 ...

  6. P7988-[USACO21DEC] HILO G【set,线段树】

    正题 题目链接:https://www.luogu.com.cn/problem/P7988 题目大意 给出一个长度为nnn的排列,开始有一个数字xxx,第一次询问回答x<a1x<a_1x ...

  7. POJ 2528 Mayor's posters (离散化和线段树使用)

    还是做了线段树的题目,玩了两天也要继续看看题目了.之前就有看离散化的概念,大家可以去百度百科一下,简单转载一个例子 离散化 的大概思路 : 比如说给你一组 数据 1 4 1000 100000, 如果 ...

  8. C++线段树运用进阶:【高级数据结构】自动售票系统

    前言 线段树是什么我就不在这里详细讲解了大家在用线段树时,那些简单的题型应该都没有问题了吧? --那好,我们一起来看一道稍微复杂一点的水题吧! [高级数据结构]自动售票系统 题目描述 某次列车途径C个 ...

  9. 【XSY3367】青春野狼不做姐控偶像的梦(线段树)

    题意:给一个 1∼n1\sim n1∼n 的排列,多次询问某段区间内的值域连续子区间的个数. 区间值域连续的另一种表达方式:max−min=r−lmax-min=r-lmax−min=r−l,即 (m ...

  10. 【做练习】K-th Number(线段树)线段树的原理

    1. 题目 描述 You are working for Macrohard company in data structures department. After failing your pre ...

最新文章

  1. 看完这篇文章之后,终于明白了编译到底怎么回事
  2. Python:利用collections库实现统计单个字或单个字母的频率统计并进行降序输出、统计一个列表内重复元素并以字典形式输出
  3. 深度洞见|从起源到应用,一文详解营销界爆火的 CDP
  4. java 链接为分布式 hbase,hbase学习记录(一):hbase伪分布式安装
  5. 遍历图像方法以及注意事项
  6. 【QT】入门基础教程Qt5
  7. Cisco思科模拟器不限速下载安装 bp网盘教程
  8. C#控制台应用程序的输入输出
  9. 域名申请:一定要进行实名认证吗?
  10. 速记TCP/IP五层模型
  11. 树莓派综合项目2:智能小车(一)四轮驱动
  12. php gps 车辆定位,员工GPS解决方案
  13. 2020ICPC上海 C.Sum of Log
  14. 如何在autocad中制作幻灯片文件(.sld)
  15. [渝粤教育] 山东财经大学 国际金融 参考 资料
  16. java类名遵从法_程序员必知的Java基础:5条命名规范和8种数据类型归纳
  17. 铭瑄MS-挑战者 Z690M、铭瑄MS-挑战者 B660M XMP问题
  18. 使用STM32F103 I2C驱动SHT30
  19. keytool 工具介绍
  20. Axure 9 选择组的使用

热门文章

  1. itextpdf生成pdf,指定样式及文字水印
  2. linux os版本 32或64位查看
  3. sql server返回是星期几的函数
  4. keras+卷积神经网络HWDB手写汉字识别
  5. UVM 事务级建模TLM 单向/多向通信 端口 FIFO通信
  6. 60题计算机专业知识点,计算机考试题库:计算机考试练习题(60)
  7. 《弃子长安》第三章 月下魅影
  8. Asia/Shanghai与GMT-8的区别
  9. 星星之火-9:详解信道特性与奈奎斯特定理和香农定理
  10. 怎样做具有视觉冲击感的非主流照片