• 【最长连续零 线段树】bzoj1593: [Usaco2008 Feb]Hotel 旅馆


    最长连续零的线段树解法

    Description

    奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光。作为整个旅游的策划者和负
    责人,贝茜选择在湖边的一家著名的旅馆住宿。这个巨大的旅馆一共有N (1 <= N <= 50,000)间客房,它们在同一
    层楼中顺次一字排开,在任何一个房间里,只需要拉开窗帘,就能见到波光粼粼的湖面。 贝茜一行,以及其他慕
    名而来的旅游者,都是一批批地来到旅馆的服务台,希望能订到D_i (1 <= D_i <= N)间连续的房间。服务台的接
    待工作也很简单:如果存在r满足编号为r..r+D_i-1的房间均空着,他就将这一批顾客安排到这些房间入住;如果
    没有满足条件的r,他会道歉说没有足够的空房间,请顾客们另找一家宾馆。如果有多个满足条件的r,服务员会选
    择其中最小的一个。 旅馆中的退房服务也是批量进行的。每一个退房请求由2个数字X_i、D_i 描述,表示编号为X
    _i..X_i+D_i-1 (1 <= X_i <= N-D_i+1)房间中的客人全部离开。退房前,请求退掉的房间中的一些,甚至是所有
    ,可能本来就无人入住。 而你的工作,就是写一个程序,帮服务员为旅客安排房间。你的程序一共需要处理M (1 
    <= M < 50,000)个按输入次序到来的住店或退房的请求。第一个请求到来前,旅店中所有房间都是空闲的。

    Input

    * 第1行: 2个用空格隔开的整数:N、M
    * 第2..M+1行: 第i+1描述了第i个请求,
    如果它是一个订房请求,则用2个数字 1、D_i描述,数字间用空格隔开;
    如果它是一个退房请求,用3 个以空格隔开的数字2、X_i、D_i描述

    Output

    * 第1..??行: 对于每个订房请求,输出1个独占1行的数字:
    如果请求能被满足 ,输出满足条件的最小的r;如果请求无法被满足,输出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 #include<bits/stdc++.h>
     2 const int maxn = 50035;
     3 
     4 struct node
     5 {
     6     int val,lval,rval;
     7     int cv;
     8 }f[maxn<<2];
     9 int n,m;
    10 
    11 int read()
    12 {
    13     char ch = getchar();
    14     int num = 0;
    15     bool fl = 0;
    16     for (; !isdigit(ch); ch = getchar())
    17         if (ch=='-') fl = 1;
    18     for (; isdigit(ch); ch = getchar())
    19         num = (num<<1)+(num<<3)+ch-48;
    20     if (fl) num = -num;
    21     return num;
    22 }
    23 inline int max(int a, int b, int c){return std::max(std::max(a, b), c);}
    24 void update(int rt, int c, int lens)    //分情况更新标记
    25 {
    26     f[rt].cv = c;
    27     if (c)
    28         f[rt].val = f[rt].lval = f[rt].rval = 0;
    29     else f[rt].val = f[rt].lval = f[rt].rval = lens;
    30 }
    31 void pushdown(int rt, int l, int r)
    32 {
    33     if (f[rt].cv!=-1){
    34         update(rt<<1, f[rt].cv, l);
    35         update(rt<<1|1, f[rt].cv, r);
    36         f[rt].cv = -1;
    37     }
    38 }
    39 void pushup(int rt, int ls, int rs)        //更新标记
    40 {
    41     int l = rt<<1, r = rt<<1|1;
    42     f[rt].val = max(f[l].val, f[r].val, f[l].rval+f[r].lval);
    43     f[rt].lval = f[l].lval, f[rt].rval = f[r].rval;
    44     if (f[l].lval==ls) f[rt].lval += f[r].lval;
    45     if (f[r].rval==rs) f[rt].rval += f[l].rval;
    46 }
    47 void cover(int rt, int L, int R, int l, int r, int c)  //处理覆盖
    48 {
    49     if (L <= l&&r <= R){
    50         update(rt, c, r-l+1);
    51         return;
    52     }
    53     int mid = (l+r)>>1;
    54     pushdown(rt, mid-l+1, r-mid);
    55     if (L <= mid) cover(rt<<1, L, R, l, mid, c);
    56     if (R > mid) cover(rt<<1|1, L, R, mid+1, r, c);
    57     pushup(rt, mid-l+1, r-mid);
    58 }
    59 int query(int rt, int l, int r, int c)          //处理询问
    60 {
    61     if (f[rt].val < c) return 0;
    62     int mid = (l+r)>>1;
    63     pushdown(rt, mid-l+1, r-mid);
    64     if (f[rt<<1].val >= c) return query(rt<<1, l, mid, c);
    65     if (f[rt<<1].rval+f[rt<<1|1].lval >= c) return mid-f[rt<<1].rval+1;
    66     return query(rt<<1|1, mid+1, r, c);
    67 }
    68 void build(int rt, int l, int r)
    69 {
    70     f[rt].cv = -1, f[rt].val = f[rt].lval = f[rt].rval = r-l+1;
    71     if (l==r) return;
    72     int mid = (l+r)>>1;
    73     build(rt<<1, l, mid), build(rt<<1|1, mid+1, r);
    74 }
    75 int main()
    76 {
    77     n = read(), m = read();
    78     build(1, 1, n);
    79     for (int i=1; i<=m; i++)
    80     {
    81         int opt = read();
    82         if (opt==1){
    83             int x = read(), ans = query(1, 1, n, x);
    84             printf("%d
    ",ans);
    85             if (ans){
    86                 cover(1, ans, ans+x-1, 1, n, 1);
    87             }
    88         }else{
    89             int l = read(), r = read();
    90             cover(1, l, l+r-1, 1, n, 0);
    91         }
    92     }
    93     return 0;
    94 }

    END

  • 相关阅读:
    automatic preferred max layout width
    UIActivityIndicatorView
    collectionview不能拖动
    消除找不到文件路径的警告
    保存图片到本地和相册
    svn上传.a文件
    UILabel copyWithZone:]: unrecognized selector sent to instance 0x7fd662d8f9b0
    NSString NSURL
    iOS 定位功能
    前端实现左右翻页功能Demo
  • 原文地址:https://www.cnblogs.com/antiquality/p/9415987.html
Copyright © 2020-2023  润新知