MiYu原创, 转帖请注明 : 转载自 ______________白白の屋  

题目地址 :

http://poj.org/problem?id=3667

题目描述:

Hotel
Time Limit: 3000MS Memory Limit: 65536K
Total Submissions: 2993 Accepted: 1143

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 Di contiguous 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, andDi

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: 插入线段

2: 删除线段

上面2种操作可以同一个函数实现, 只需要传一个标志量就行

3: 查询可用区间

题目的数据意思 : 1 3   表示 要申请最左边的满足要求的线段, 输出线段的左端点, 同时更新线段树,   没有满足要求的线段时输出0 , 这时不要更新线段 !!! 这里WA几次 杯具

2 5 5 表示 删除以5为左端点, 长为5 的线段  , 就是 删除[5,9].

具体请看 代码注释 :

代码

/*
Mail to   : miyubai@gamil.com
Link      : http://www.cnblogs.com/MiYu  || http://www.cppblog.com/MiYu
Author By : MiYu
Test      : 1
Complier  : g++ mingw32-3.4.2
Program   : PKU_3667
Doc Name  : HOTEL
*/
//#pragma warning( disable:4789 )
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <utility>
#include <queue>
#include <stack>
#include <list>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
using namespace std;
inline int max ( int a, int b ) {
       return a > b ? a : b;       
}
struct segTree {
       int left, right, lVal, rVal, mVal, cov;// cov -- >  0: 线段为空   1: 线段为满  -1:2种情况都有 
       int mid () { return (left+right)>>1; }
       int dis () { return right - left + 1; }
       void set ( int flag ) { // 0: 线段为空   1: 线段为满 
            if ( flag ){
                 cov = 1;
                 lVal = rVal = mVal = 0;  
            } else {
                 cov = 0;
                 lVal = rVal = mVal = right - left + 1;     
            }
       }     
}seg[160000];
void creat ( int left, int right, int rt = 1 ) {   // 初始化线段 
     seg[rt].left = left;
     seg[rt].right = right;
     seg[rt].set (0);
     if ( left == right ) return;
     int LL = rt << 1, RR = rt << 1 | 1, mid = seg[rt].mid();  
     creat ( left, mid, LL );
     creat ( mid + 1, right, RR );  
}
void modify ( int left, int right, int flag, int rt = 1 ) {
     if ( seg[rt].left >= left && seg[rt].right <= right ) {   //如果线段被覆盖,  直接按flag标记处理,返回 
         seg[rt].set ( flag );   return;
     }     
     int LL = rt << 1, RR = rt << 1 | 1, mid = seg[rt].mid();
     if ( seg[rt].cov != -1 ) {     // 如果线段不是混合情况(即线段是被覆盖的), 把标志下传 
          seg[LL].cov = seg[RR].cov = seg[rt].cov;
          seg[LL].set ( seg[LL].cov );   
          seg[RR].set ( seg[RR].cov );
     } 
     if ( right <= mid ) modify ( left, right, flag, LL );    //递归更新线段 
     else if ( left > mid ) modify ( left, right, flag, RR );
     else {
           modify ( left, mid, flag, LL );
           modify ( mid + 1, right, flag, RR );     
     }
     if ( seg[LL].cov == 0 && seg[RR].cov == 0 ) seg[rt].cov = 0; //线段为空 
     else if ( seg[LL].cov == 1 && seg[RR].cov == 1 ) seg[rt].cov = 1; //线段满 
     else seg[rt].cov = -1;  // 2种情况都有 
     seg[rt].mVal = max(seg[LL].rVal+seg[RR].lVal,max(seg[LL].mVal, seg[RR].mVal)); // 线段的更新,  经典部分
     seg[rt].lVal = seg[LL].lVal + ( seg[LL].cov == 0 ? seg[RR].lVal : 0 );
     seg[rt].rVal = seg[RR].rVal + ( seg[RR].cov == 0 ? seg[LL].rVal : 0 );
}
int query ( int val, int rt = 1 ) {
    int LL = rt << 1, RR = rt << 1 | 1, mid = seg[rt].mid();
    if ( seg[rt].cov == 0 && seg[rt].mVal >= val ) {   //线段为空,且可用,直接返回线段左端点 
             return seg[rt].left;
    } else if ( seg[rt].cov == -1 ) {   //分三种 情况处理  左   左右    右  处理   
         if ( seg[LL].mVal >= val ) return query ( val, LL );
         else if ( seg[LL].rVal + seg[RR].lVal >= val ) return mid - seg[LL].rVal + 1;
         else if ( seg[RR].mVal >= val )return query ( val, RR );  
    }   
    return 0;
}
int main ()
{
    int N, M, left, right, val, choice;
    while ( scanf ( "%d%d", &N,&M ) == 2 ) {
           creat ( 1, N );
           while ( M -- ) {
                  scanf ( "%d", &choice );
                  switch ( choice ) {
                          case 1 : scanf ( "%d",&val );
                                   printf ( "%d\n", left = query ( val ) );
                                   if ( left != 0 ) {
                                        right = left + val - 1;
                                        modify ( left, right, 1 );
                                   }
                                   break;
                          case 2 : scanf ( "%d%d",&left, &val );
                                   right = left + val - 1;
                                   modify ( left, right, 0 );
                                   break;       
                  }       
           }      
    }
    return 0;
}

转载于:https://www.cnblogs.com/MiYu/archive/2010/10/07/1845197.html

PKU 3667 HDOJ 3667 Hotel ACM 3667 IN HDU相关推荐

  1. HDU 2573 HDOJ 2573 Typing ACM 2573 IN HDU

    MiYu原创, 转帖请注明 : 转载自 ______________白白の屋   纯模拟, 没什么好说的, 直接代码 代码 /* Mail to   : miyubai@gamil.com My Bl ...

  2. Hotel POJ - 3667(线段树 + 区间合并

    题意: 给定长度为n的区间 ,有2个操作: 操作1: 在区间中靠左放k个元素,输出新放入元素中最左边的位置,如果放不下输出 0: 操作2 : 清空 l 到 l+w-1这一段区间的元素 这里有一个状态转 ...

  3. HDOJ 1157 HDU 1157 Who's in the Middle ACM 1157 IN HDU

    MiYu原创, 转帖请注明 : 转载自 ______________白白の屋   题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=1157 题目描述: ...

  4. HDOJ 1874 HDU 1874 畅通工程续 ACM 1874 IN HDU

    MiYu原创, 转帖请注明 : 转载自 ______________白白の屋 题目地址:          http://acm.hdu.edu.cn/showproblem.php?pid=1874 ...

  5. HDOJ HDU 2080 夹角有多大II ACM 2080 IN HDU

    MiYu原创, 转帖请注明 : 转载自 ______________白白の屋 题目地址:          http://acm.hdu.edu.cn/showproblem.php?pid=2080 ...

  6. HDOJ 1213 HDU 1213 How Many Tables ACM 1213 IN HDU

    MiYu原创, 转帖请注明 : 转载自 ______________白白の屋 题目地址:          http://acm.hdu.edu.cn/showproblem.php?pid=1213 ...

  7. HDOJ 1016 HDU 1016 Prime Ring Problem ACM 1016 IN HDU

    题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=1016 题目描述: Prime Ring Problem Time Limit: 4000/2000 ...

  8. HDOJ 1253 HDU 1253 胜利大逃亡 ACM 1253 IN HDU

    MiYu原创, 转帖请注明 : 转载自 ______________白白の屋   题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=1253 题目描述: ...

  9. HDOJ HDU 1106 排序 ACM 1106 IN HDU

    //MiYu原创, 转帖请注明 : 转载自 ______________白白の屋 题目地址 :             http://acm.hdu.edu.cn/showproblem.php?pi ...

最新文章

  1. 链家混三个月底薪_链家悲惨工作经历,新人参考
  2. ubuntu java 全屏显示_java 在ubuntu下实现全屏,上面的状态栏依然显示。如下图,不想要上面的状态栏...
  3. 高考完?入门级的开源项目带你开启编程之旅
  4. 用户操作-用户添加操作代码实现
  5. python自动操作微信_Python+Appium 自动化操作微信入门看这一篇就够了
  6. vue --- [全家桶] Vuex
  7. win10计算机从桌面消失了,Windows10家庭版程序窗口在桌面上消失了解决方法
  8. Arduino笔记-WeMos D1通过HTTP亮熄灯
  9. canvas画条形图 微信小程序_小程序-引入 echart 图表画圆饼图
  10. 接口测试文件上传(python+requests)
  11. 2018-2019-2 20165118 《网络对抗技术》Exp4 恶意代码分析
  12. 杨澜给80后女孩子的14个忠告
  13. android手机内存单位 吉字节,Android8.1 吉字节问题
  14. 无线渗透(下)—企业级WPA破解
  15. POJ 2856 Y2K Accounting Bug【简单暴力】
  16. android6.0 cta认证,手机cta认证要求有哪些?
  17. ps中如何批量修改图片
  18. Windows 桌面主题 1.2
  19. 前端iframe标签介绍及使用
  20. debian基本设置以及配置XManager远程登录桌面、命令行设置、Xftp上传下载文件

热门文章

  1. HTML基本语法九 会移动的文字
  2. 单一IP地址静态NAT实验环境
  3. C++ main函数中参数argc和argv相关定义与研究
  4. 每天Leetcode 刷题 初级算法篇-数学问题-罗马数字转整数
  5. java多线程交替打印_java多线程 更优雅的实现线程同步:交替打印A、B LockSupport实现...
  6. 从集合(内存)中创建RDD
  7. scala的函数化编程
  8. 谷歌搜索363搜索引擎入口_SEO谷歌搜索引擎优化到底有啥好?
  9. Pandas——处理丢失的数据(含NaN的数据)
  10. github代码管理总结