zoukankan      html  css  js  c++  java
  • 1593: [Usaco2008 Feb]Hotel 旅馆 (线段树)

    1593: [Usaco2008 Feb]Hotel 旅馆

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 451  Solved: 262
    [Submit][Status][Discuss]

    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

    HINT

     

    Source

    Gold

      1 /*
      2     建一颗线段树 
      3     储存四个信息 lm 代表从区间左端点开始向右连续最长为空的序列长度
      4                  rm 代表从区间右端点开始向左连续最长为空的序列长度
      5                  m  代表区间内连续最长为空的序列长度
      6                  s  代表区间长度 
      7     维护 前三个信息 
      8     用 s 判断区间是否可用 从而更新 lm rm 和 m 
      9     具体看操作 
     10 */
     11 #include<cstdio>
     12 #include<iostream>
     13 #define MAXN 100010
     14 
     15 using namespace std;
     16 
     17 struct de {
     18     int l,r;
     19     int s,lm,rm,m;
     20     int tag;
     21 };
     22 de tr[MAXN<<2];
     23 
     24 int n,T,opt,x,y;
     25 
     26 inline void read(int&x) { 
     27     int f=1;x=0;char c=getchar(); 
     28     while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();} 
     29     while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-48;c=getchar();} 
     30     x=x*f; 
     31 } 
     32 
     33 inline void up(int now) {
     34     if(tr[now<<1].m==tr[now<<1].s) tr[now].lm=tr[now<<1].m+tr[now*2+1].lm;
     35     else tr[now].lm=tr[now<<1].lm;
     36     if(tr[now*2+1].m==tr[now*2+1].s) tr[now].rm=tr[now*2+1].m+tr[now<<1].rm;
     37     else tr[now].rm=tr[now*2+1].rm;
     38     tr[now].m=max(max(tr[now<<1].m,tr[now*2+1].m),tr[now<<1].rm+tr[now*2+1].lm);
     39     return;
     40 }
     41 
     42 inline void down(int now) {
     43     if(tr[now].tag==1) {
     44         tr[now<<1].tag=tr[now*2+1].tag=tr[now].tag;
     45         tr[now<<1].lm=tr[now<<1].rm=tr[now<<1].m=0;
     46         tr[now*2+1].lm=tr[now*2+1].m=tr[now*2+1].rm=0;
     47     }
     48     if(tr[now].tag==2) {
     49         tr[now<<1].tag=tr[now*2+1].tag=tr[now].tag;
     50         tr[now<<1].lm=tr[now<<1].rm=tr[now<<1].m=tr[now<<1].s;
     51         tr[now*2+1].lm=tr[now*2+1].m=tr[now*2+1].rm=tr[now*2+1].s;
     52     }
     53     tr[now].tag=0;
     54 }
     55 
     56 void build_tree(int now,int l,int r) {
     57     tr[now].l=l;tr[now].r=r;
     58     tr[now].lm=tr[now].rm=tr[now].m=tr[now].s=r-l+1;
     59     if(l==r) return;
     60     int mid=(l+r)>>1;
     61     build_tree(now<<1,l,mid);
     62     build_tree(now*2+1,mid+1,r);
     63     return;
     64 }
     65 
     66 int query(int now,int l,int r,int len) {
     67     if(tr[now].l==tr[now].r) return l;
     68     if(tr[now].tag) down(now);
     69     int mid=(tr[now].l+tr[now].r)>>1;
     70     if(tr[now<<1].m>=len) return query(now<<1,l,r,len);
     71     if(tr[now<<1].rm+tr[now*2+1].lm>=len) return mid-tr[now<<1].rm+1;
     72     else return query(now*2+1,mid+1,r,len);
     73 }
     74 
     75 void modify(int now,int l,int r,int d) {
     76     if(l<=tr[now].l&&r>=tr[now].r) {
     77         if(d==1) tr[now].lm=tr[now].rm=tr[now].m=0;
     78         else tr[now].lm=tr[now].rm=tr[now].m=tr[now].s;
     79         tr[now].tag=d;
     80         return;
     81     }
     82     if(tr[now].tag) down(now);
     83     int mid=(tr[now].l+tr[now].r)>>1;
     84     if(l<=mid) modify(now<<1,l,r,d);
     85     if(r>mid) modify(now*2+1,l,r,d);
     86     up(now);
     87 }
     88 
     89 int main() {
     90     read(n);read(T);
     91     build_tree(1,1,n);
     92     while(T--) {
     93         read(opt);
     94         if(opt==1) {
     95             read(x);
     96             if(tr[1].m<x) {printf("0
    ");continue;}
     97             int pos=query(1,1,n,x);
     98             printf("%d
    ",pos);
     99             modify(1,pos,pos+x-1,1);
    100         }
    101         else {
    102             read(x);read(y);
    103             modify(1,x,y+x-1,2);
    104         }
    105     }
    106     return 0;
    107 }
    题解


    作者:乌鸦坐飞机
    出处:http://www.cnblogs.com/whistle13326/
    新的风暴已经出现 怎么能够停止不前 穿越时空 竭尽全力 我会来到你身边 微笑面对危险 梦想成真不会遥远 鼓起勇气 坚定向前 奇迹一定会出现

     
  • 相关阅读:
    四叉树编码存储的实现
    窗体之间传递值的几种方法
    常见的六种排序算法实现
    OracleHelper类
    c#动态加载dll文件
    STL学习系列九:Map和multimap容器
    STL学习系列八:Set和multiset容器
    STL学习系列七:优先级队列priority_queue容器
    STL学习系列六:List容器
    STL学习系列五:Queue容器
  • 原文地址:https://www.cnblogs.com/whistle13326/p/7308772.html
Copyright © 2011-2022 走看看