• [POJ3667]Hotel(线段树,区间合并,重写)


     

    题目链接:http://poj.org/problem?id=3667

    题意:有一个hotel有n间房子,现在有2种操作:

    1 a,check in,表示入住。需要a间连续的房子。返回尽量靠左的房间编号并更新。

    2 a b,check out,从a开始退房,一共退到a+b-1。

    seg数组l表示从左边开始数空房子的个数,r表示从右边数空房子的个数,s表示一共最多是有s个连续的空房子。

    add作为延迟标记有3种状态:-1表示不操作,0表示退房,1表示入住。

    重写1A,感觉很爽。

      1 #include <algorithm>
      2 #include <iostream>
      3 #include <iomanip>
      4 #include <cstring>
      5 #include <climits>
      6 #include <complex>
      7 #include <cassert>
      8 #include <cstdio>
      9 #include <bitset>
     10 #include <vector>
     11 #include <deque>
     12 #include <queue>
     13 #include <stack>
     14 #include <ctime>
     15 #include <set>
     16 #include <map>
     17 #include <cmath>
     18 using namespace std;
     19 
     20 #define lrt rt << 1
     21 #define rrt rt << 1 | 1
     22 typedef struct Seg { int sign, ls, ms, rs; }Seg;
     23 const int maxn = 50500;
     24 Seg seg[maxn<<2];
     25 int val[maxn];
     26 int n, m;
     27 
     28 void pushup(int l, int r, int rt) {
     29     int mid = (l + r) >> 1;
     30     int ll = mid - l + 1, rr = r - mid;
     31     seg[rt].ls = seg[lrt].ls, seg[rt].rs = seg[rrt].rs;
     32     if(seg[lrt].rs==ll) seg[rt].ls += seg[rrt].ls;
     33     if(seg[rrt].ls==rr) seg[rt].rs += seg[lrt].rs;
     34     seg[rt].ms = max(seg[lrt].ms, seg[rrt].ms);
     35     seg[rt].ms = max(seg[rt].ms, seg[lrt].rs+seg[rrt].ls);
     36 }
     37 
     38 void pushdown(int l, int r, int rt) {
     39     int mid = (l + r) >> 1;
     40     if(seg[rt].sign == -1) return;
     41     if(seg[rt].sign == 1) {
     42         seg[lrt].sign = seg[rrt].sign = 1;
     43         seg[lrt].ms = seg[rrt].ms = 0;
     44         seg[lrt].ls = seg[rrt].ls = 0;
     45         seg[lrt].rs = seg[rrt].rs = 0;
     46     }
     47     else {
     48         seg[lrt].sign = seg[rrt].sign = 0;
     49         seg[lrt].ls = seg[lrt].ms = seg[lrt].rs = mid - l + 1;
     50         seg[rrt].ls = seg[rrt].ms = seg[rrt].rs = r - mid;
     51     }
     52     seg[rt].sign = -1;
     53 }
     54 
     55 void build(int l, int r, int rt) {
     56     if(l == r) {
     57         seg[rt].sign = -1;
     58         seg[rt].ls = seg[rt].ms = seg[rt].rs = r - l + 1;
     59         return;
     60     }
     61     int mid = (l + r) >> 1;
     62     build(l, mid, lrt);
     63     build(mid+1, r, rrt);
     64     pushup(l, r, rt);
     65 }
     66 
     67 void update(int L, int R, int sign, int l, int r, int rt) {
     68     if(L <= l && r <= R) {
     69         if(sign) seg[rt].ls = seg[rt].ms = seg[rt].rs = 0;
     70         else seg[rt].ls = seg[rt].ms = seg[rt].rs = r - l + 1;
     71         seg[rt].sign = sign;
     72         return;
     73     }
     74     pushdown(l, r, rt);
     75     int mid = (l + r) >> 1;
     76     if(L <= mid) update(L, R, sign, l, mid, lrt);
     77     if(mid < R) update(L, R, sign, mid+1, r, rrt);
     78     pushup(l, r, rt);
     79 }
     80 
     81 int query(int len, int l, int r, int rt) {
     82     if(l == r) return rt;
     83     pushdown(l, r, rt);
     84     int mid = (l + r) >> 1;
     85     if(seg[lrt].ms >= len) return query(len, l, mid, lrt);
     86     else if(seg[lrt].rs + seg[rrt].ls >= len) return mid - seg[lrt].rs + 1;
     87     else return query(len, mid+1, r, rrt);
     88 }
     89 
     90 int main() {
     91     // freopen("in", "r", stdin);
     92     int x, l, r;
     93     while(~scanf("%d%d",&n,&m)) {
     94         memset(val, 0, sizeof(val));
     95         build(1, n, 1);
     96         while(m--) {
     97             scanf("%d",&x);
     98             if(x == 1) {
     99                 scanf("%d",&l);
    100                 if(l > seg[1].ms) {
    101                     puts("0");
    102                     continue;
    103                 }
    104                 r = query(l, 1, n, 1);
    105                 printf("%d
    ", r);
    106                 update(r, r+l-1, 1, 1, n, 1);
    107             }
    108             else {
    109                 scanf("%d%d",&l,&r);
    110                 update(l, l+r-1, 0, 1, n, 1);
    111             }
    112         }
    113     }
    114     return 0;
    115 }
  • 相关阅读:
    DB2 9 基础根基(730 测验)认证指南,第 2 部门: 安适性(1)
    DB2 9 根底(730 考验)认证指南,第 3 部门: 访问 DB2 数据(7)
    IT人 软件工程师的务实职业生涯规划
    《Delphi 算法与数据结构》学习与感悟[8]: 单向链表的添加、删除与遍历
    《Delphi 算法与数据结构》简介及下载
    《Delphi 算法与数据结构》学习与感悟[1]: 通过 "顺序查找" 与 "二分查找" 说明算法的重要性
    《Delphi 算法与数据结构》学习与感悟[2]: 数据对齐
    学习 TTreeView [14] StateIndex(状态图标)、OverlayIndex(叠加图标)
    《Delphi 算法与数据结构》学习与感悟[3]: 获取一个字节中非空位的个数
    《Delphi 算法与数据结构》学习与感悟[6]: 一个简单的"单向链表"
  • 原文地址:https://www.cnblogs.com/kirai/p/6821004.html
Copyright © 2020-2023  润新知