Description

The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a vacation on the sunny shores of Lake Superior. Bessie, ever the competent travel agent, has named the Bullmoose Hotel on famed Cumberland Street as their vacation residence. This immense hotel has N (1 ≤ N ≤ 50,000) rooms all located on the same side of an extremely long hallway (all the better to see the lake, of course).

The cows and other visitors arrive in groups of size Di (1 ≤ Di ≤ N) and approach the front desk to check in. Each group i requests a set of Dicontiguous rooms from Canmuu, the moose staffing the counter. He assigns them some set of consecutive room numbers r..r+Di-1 if they are available or, if no contiguous set of rooms is available, politely suggests alternate lodging. Canmuu always chooses the value of r to be the smallest possible.

Visitors also depart the hotel from groups of contiguous rooms. Checkout i has the parameters Xi and Di which specify the vacating of rooms Xi ..Xi+Di-1 (1 ≤ Xi ≤ N-Di+1). Some (or all) of those rooms might be empty before the checkout.

Your job is to assist Canmuu by processing M (1 ≤ M < 50,000) checkin/checkout requests. The hotel is initially unoccupied.

Input

* Line 1: Two space-separated integers: N and M
* Lines 2..M+1: Line i+1 contains request expressed as one of two possible formats: (a) Two space separated integers representing a check-in request: 1 and D(b) Three space-separated integers representing a check-out: 2, Xi, and Di

Output

* Lines 1.....: For each check-in request, output a single line with a single integer r, the first room in the contiguous sequence of rooms to be occupied. If the request cannot be satisfied, output 0.

Sample Input

10 6
1 3
1 3
1 3
1 3
2 5 5
1 6

Sample Output

1
4
7
0
5 看了好久的题目,结果还是去搜了一下题解,哎,实力不够,

去掉题目背景,就是给你一个[1,n]的区间,初始时,整个区间为空,在区间进行俩个操作:

1) 输入 1 D :在区间上从左到右找出第一个连续的长度为D 的空间,并将该区间填满,输出区间的端点,若不存在,输出0

2) 输入 2 a b: 将区间[a,a+b-1] 填满

这是线段树比较难的一种了吧,区间合并,其中我参照ACM大牛的做法,用msum表示当前节点的最长连续区间长度,lsum表示当前节点以左端点位起点的最长连续长度,同理,rsum

表示当前节点以右端点为结尾的最长区间长度,代码中我会加入具体注释,以便以后自己理解:

#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#include<algorithm>
using namespace std;

#define INF 0x3f3f3f3f
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

const int MX = 55555;
int msum[MX<<2], lsum[MX<<2], rsum[MX<<2], cover[MX<<2];//cover表示要执行的操作,要初始化为负一

void PushUp(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];//如果右边区间最大了,那就合并左儿子的右区间
  msum[rt] = max(lsum[rt<<1|1] + rsum[rt<<1], max(msum[rt<<1], msum[rt<<1|1]));//取最长的连续区间长度记录
}

void Build(int l, int r, int rt) {
  msum[rt] = lsum[rt] = rsum[rt] = r - l + 1;//初始化时每个区间都是最大值
  cover[rt] = -1;/*之所以要初始化为-1,是因为有延迟标记的存在,遇到-1则不用继续向下更新了,如果要清除或者填满更深的节点,把延迟标记往下传递填满是1,清除是0*/
  if (l == r) {
  return ;
  }
  int m = (l + r)>>1;
  Build(lson);
  Build(rson);
}
void PushDown(int rt, int len) {
  if (cover[rt] != -1) {
    cover[rt<<1] = cover[rt<<1|1] = cover[rt];
    msum[rt<<1] = lsum[rt<<1] = rsum[rt<<1] = cover[rt] ? 0 : len - (len>>1);/*下面还会遇到相似的代码,大致的意思是如果操作是0(清空)就把连续区间变到最大,

因为清空了嘛*/
    msum[rt<<1|1] = lsum[rt<<1|1] = rsum[rt<<1|1] = cover[rt] ? 0 : (len>>1);
    cover[rt] = -1;
  }
}

void UpDate(int L, int R, int add, int l, int r, int rt) {
  if (L <= l && r <= R) {
  cover[rt] = add;//记录操作
  msum[rt] = lsum[rt] = rsum[rt] = add ? 0 : r - l + 1;
  return ;
}
PushDown(rt, r - l + 1);
  int m = (l + r)>>1;
  if (L <= m) UpDate(L, R, add, lson);
  if (R > m) UpDate(L, R, add, rson);
  PushUp(rt, r - l + 1);
}

int Query(int q, int l, int r, int rt) {
  if (l == r) {
  return l;
  }
  PushDown(rt, r - l + 1);
  int m = (l + r)>>1;
  if (msum[rt<<1] >= q) return Query(q, lson);
  else if (lsum[rt<<1|1] + rsum[rt<<1] >= q) return m - rsum[rt<<1] + 1;
  else return Query(q, rson);

}
int main() {
  //freopen("input.txt", "r", stdin);
  int n, m;
  while (scanf("%d %d", &n, &m) != EOF) {
    Build(1, n, 1);
    while (m--) {
      int Q;
      scanf("%d", &Q);
      if (Q == 1) {
        int a;
        scanf("%d", &a);
        if (msum[1] < a) {//如果最大的连续区间都先于a,就没有答案了
        puts("0");
        continue;
       }
        int ans = Query(a, 1, n, 1);
        printf("%d\n", ans);
        UpDate(ans, ans + a - 1, 1, 1, n, 1);
       } else {
        int a, b;
        scanf("%d %d", &a, &b);
        UpDate(a, a + b - 1, 0, 1, n, 1);
       }
     }
   }
   return 0;
}

HDU - Hotel的更多相关文章

  1. E - Tunnel Warfare HDU - 1540 F - Hotel G - 约会安排 HDU - 4553 区间合并

    E - Tunnel Warfare HDU - 1540 对这个题目的思考:首先我们已经意识到这个是一个线段树,要利用线段树来解决问题,但是怎么解决呢,这个摧毁和重建的操作都很简单,但是这个查询怎么 ...

  2. hdu 2992 Hotel booking

    http://acm.hdu.edu.cn/showproblem.php?pid=2992 #include <cstdio> #include <cstring> #inc ...

  3. HDU 2585 [Hotel]字符串递归处理

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2585 题目大意:马克思要找个曾经去过的很好的旅馆,可惜他记不完整旅馆的名字.他有已知的部分信息和可能的 ...

  4. HDU 2585 Hotel(字符串的模糊匹配+递归)

    Problem Description Last year summer Max traveled to California for his vacation. He had a great tim ...

  5. Find the hotel HDU - 3193 (ST表RMQ)

    Summer again! Flynn is ready for another tour around. Since the tour would take three or more days, ...

  6. HDU 2992 Hotel booking(BFS+DFS 或者 SPFA+Floyd)

    点我看题目 题意 : 一个司机要从1点到达n点,1点到n点中有一些点有宾馆,司机的最长开车时间不能超过10小时,所以要在10小时之内找到宾馆休息,但是为了尽快的走到n点,问最少可以经过几个宾馆. 思路 ...

  7. Find the hotel HDU - 3193(RMQ)

    题意: 有n个旅馆,从这n个旅馆中找出若干个旅馆,使得这若干个旅馆满足这样的条件:不能从其它和剩下的旅馆中找到一个价格和距离都小于这个旅馆的旅馆... 解析: 按price 排序,若price相同, ...

  8. HDU 5992/nowcoder 207K - Finding Hotels - [KDTree]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5992 题目链接:https://www.nowcoder.com/acm/contest/207/K ...

  9. HDU_3193_Find the hotel

    Find the hotel Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

随机推荐

  1. 理解Java中的final和static关键字

    回顾这两个关键字前,先考虑一个问题: Static变量存储在JVM中的位置,或者说static变量是如何被加载的? JVM会把类的静态方法和静态变量在类加载的过程中读入方法区(Method Area) ...

  2. 重温WCF之WCF抛出异常的处理SOAP Fault(十二)

    1.(服务端)抛出和(客户端)捕获SOAP Fault 当我们需要客户端获取到WCF服务端的抛出的异常的时候,使用FaultException类 WCF类库在System.ServiceModel命名 ...

  3. Android性能优化系列 + Android官方培训课程中文版

    Android性能优化典范 - 第6季 http://hukai.me/android-performance-patterns-season-6/   Android性能优化典范 - 第5季 htt ...

  4. 情定XMLA,割舍不下的XAML

    俗话说,不玩Silverlight的APP Developer,在DBA圈里就不是好的数据分析师.嗯,你没看错,题目里,一样东西是XMLA,一样东西是XAML.前者是用来玩SSAS的 ,一样是用来玩S ...

  5. Android学习二_八:Animation的使用(一) (转)

    一.Animations介绍 Animations是一个实现android UI界面动画效果的API,Animations提供了一系列的动画效果,可以进行旋转.缩放.淡入淡出等,这些效果可以应用在绝大 ...

  6. Ubuntu14 搭载vim环境查看源码

    首先是下载完整的vim74,然后编译安装.遗憾的是当编译时,没有开启图形界面. 在安装新版本的Vim之前,你需要卸载原来安装的老版本Vim,依次在终端下执行下列命令: sudo apt-get rem ...

  7. SQLServer 维护脚本分享(07)IO

    sp_helpfile --当前数据库文件分配情况 sp_spaceused --当前db空间大小(有时不准) sp_spaceused 'dbo.user' --指定表的空间大小(有时不准) sp_ ...

  8. filter应用案例三:解决全站编码问题

    1 说明 乱码问题: 获取请求参数中的乱码问题: POST请求:request.setCharacterEncoding("utf-8"): GET请求:new String(re ...

  9. ce游戏内存修改器(Cheat Engine)

    ce修改器(Cheat Engine)一款专门修改内存修改编辑的游戏工具它包括16进制编辑,反汇编程序,内存查找工具新版6.1 版的CE与6.0 最大的区别就是添加了修改器制作工具,比之前 5.6.1 ...

  10. [转载]void及void*的深度剖析

    void的含义 void即"无类型",void *则为"无类型指针",可以指向任何数据类型. void指针使用规范 ①void指针可以指向任意类型的数据,亦即可 ...