zoukankan      html  css  js  c++  java
  • poj 3667 Hotel (线段树)

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

    Hotel
    Time Limit: 3000MS   Memory Limit: 65536K
    Total Submissions: 9484   Accepted: 4066

    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 Di (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
    

    Source

     
    【题解】:
      线段树:
    struct Nod
    {
        int l,r;
        int ml,mm,mr;  //左边的空位,区间最大的空位,右边的空位
    }node[N<<2];
    查找的时候优先向左边查找插入;
    注意各种状态的更新
    详见代码
     
    【code】:
      1 /**
      2 judge status: Accepted      exe.time:563MS
      3 exe.memory 2712K    language:C++
      4 */
      5 
      6 #include<iostream>
      7 #include<stdio.h>
      8 #include<string.h>
      9 #include<algorithm>
     10 
     11 #define N 50010
     12 
     13 #define lson p<<1
     14 #define rson p<<1|1
     15 
     16 using namespace std;
     17 
     18 struct Nod
     19 {
     20     int l,r;
     21     int ml,mm,mr;  //左边的空位,区间最大的空位,右边的空位
     22 }node[N<<2];
     23 
     24 int id;
     25 
     26 void building(int l,int r,int p)//建树
     27 {
     28     node[p].l = l;
     29     node[p].r = r;
     30     node[p].mm=node[p].mr=node[p].ml= r-l+1;
     31     if(l==r)    return;
     32     int mid = (l+r)>>1;
     33     building(l,mid,lson);
     34     building(mid+1,r,rson);
     35 }
     36 
     37 void judgeChange(int p)  //向下更新,状态延迟标记,当搜索到整个区间一样时,向下更新一层,然后进行操作
     38 {
     39     if(node[p].mm==node[p].r-node[p].l+1)
     40     {
     41         node[lson].ml=node[lson].mm=node[lson].mr=node[lson].r-node[lson].l+1;
     42         node[rson].ml=node[rson].mm=node[rson].mr=node[rson].r-node[rson].l+1;
     43     }
     44     if(node[p].mm==0)
     45     {
     46         node[lson].ml=node[lson].mm=node[lson].mr=0;
     47         node[rson].ml=node[rson].mm=node[rson].mr=0;
     48     }
     49 }
     50 
     51 void findId(int p,int val)  //查找可以开房间的起始位置
     52 {
     53     if(node[p].l==node[p].r&&val==1) //当val为1并且已经达到叶子节点,说明没有孩子了,不必再往下查找
     54     {
     55         id = node[p].l;
     56         return;
     57     }
     58     judgeChange(p);  //状态延迟标记更新
     59     if(node[p].mm>=val)  //区间最大连续>=val时
     60     {
     61         if(node[lson].mm>=val)  //优先左边搜索
     62         {
     63             findId(lson,val);
     64         }
     65         else if(node[rson].ml+node[lson].mr>=val)  //然后中间
     66         {
     67             id = node[lson].r - node[lson].mr + 1;
     68         }
     69         else if(node[rson].mm>=val)  //最后右边
     70         {
     71             findId(rson,val);
     72         }
     73     }
     74 }
     75 
     76 void Up(int p)  //向上更新状态
     77 {
     78     node[p].ml = node[lson].ml;
     79     node[p].mr = node[rson].mr;
     80     if(node[lson].ml==node[lson].r-node[lson].l+1)
     81     {
     82         node[p].ml+=node[rson].ml;
     83     }
     84     if(node[rson].mr==node[rson].r-node[rson].l+1)
     85     {
     86         node[p].mr+=node[lson].mr;
     87     }
     88     node[p].mm = max(node[lson].mm,node[rson].mm);
     89     node[p].mm = max(node[p].mm,node[lson].mr+node[rson].ml);
     90     node[p].mm = max(node[p].mm,node[p].ml);
     91     node[p].mm = max(node[p].mm,node[p].mr);
     92 }
     93 
     94 void update(int l,int r,int p,int op) //更新
     95 {
     96     if(node[p].l==l&&node[p].r==r)
     97     {
     98         if(op==1)   node[p].ml=node[p].mm=node[p].mr=0;  //执行操作1
     99         else    node[p].ml=node[p].mm=node[p].mr=r-l+1;  //执行操作2
    100         return;
    101     }
    102     judgeChange(p);  //状态延迟标记更新
    103     int mid = (node[p].l+node[p].r)>>1;
    104     if(r<=mid)  update(l,r,lson,op);
    105     else if(l>mid)  update(l,r,rson,op);
    106     else
    107     {
    108         update(l,mid,lson,op);
    109         update(mid+1,r,rson,op);
    110     }
    111     Up(p);  //由左右孩子节点向上更新ml,mm,mr值
    112 }
    113 
    114 
    115 int main()
    116 {
    117     int n,m;
    118     scanf("%d%d",&n,&m);
    119     building(1,n,1);
    120     while(m--)
    121     {
    122         int op,a,b;
    123         scanf("%d",&op);
    124         if(op==1)
    125         {
    126             scanf("%d",&a);
    127             id = 0;
    128             findId(1,a);  //查找可插入位置
    129             printf("%d
    ",id);
    130             if(id)   update(id,id+a-1,1,1);   //在id位置插入a个数,即在[id,id+a-1]插入
    131         }
    132         else if(op==2)
    133         {
    134             scanf("%d%d",&a,&b);
    135             update(a,a+b-1,1,2);  //在a位置删除b个数,即把在[a,a+b-1]区间清空
    136         }
    137     }
    138     return 0;
    139 }
  • 相关阅读:
    spark streaming 概述
    spark sql 的性能调优
    LeetCode 106. Construct Binary Tree from Inorder and Postorder Traversal (用中序和后序树遍历来建立二叉树)
    LeetCode 105. Construct Binary Tree from Preorder and Inorder Traversal (用先序和中序树遍历来建立二叉树)
    LeetCode 90. Subsets II (子集合之二)
    LeetCode 88. Merge Sorted Array(合并有序数组)
    LeetCode 81. Search in Rotated Sorted Array II(在旋转有序序列中搜索之二)
    LeetCode 80. Remove Duplicates from Sorted Array II (从有序序列里移除重复项之二)
    LeetCode 79. Word Search(单词搜索)
    LeetCode 78. Subsets(子集合)
  • 原文地址:https://www.cnblogs.com/crazyapple/p/3235753.html
Copyright © 2011-2022 走看看