zoukankan      html  css  js  c++  java
  • 刷题总结——旅馆(bzoj1593线段树)

    题目:

    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

    题解:

    线段树维护区间连续最大值,区间左端点连续值,区间右端点连续值即可·····

    我这里tag标记打了两个··一个订房一个退房···注意在打其中一个标记时把另外一个标记清空·····

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<ctime>
    #include<cctype>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    const int N=5e4+5;
    int n,m,trle[N*4],trri[N*4],trmx[N*4],tagclear[N*4],tagfull[N*4];
    inline int R()
    {
      char c;int f=0;
      for(c=getchar();c<'0'||c>'9';c=getchar());
      for(;c<='9'&&c>='0';c=getchar())
         f=(f<<3)+(f<<1)+c-'0';
      return f;
    }
    inline void update(int k,int l,int r,int mid)
    {
      if(trle[k*2]==(mid-l+1)) trle[k]=trle[k*2]+trle[k*2+1];  
      else trle[k]=trle[k*2];
      if(trri[k*2+1]==(r-mid))  trri[k]=trri[k*2+1]+trri[k*2];
      else trri[k]=trri[k*2+1];
      trmx[k]=max(max(trmx[k*2],trmx[k*2+1]),trri[k*2]+trle[k*2+1]);
    }
    inline void build(int k,int l,int r)
    {
      if(l==r)  {trle[k]=trri[k]=trmx[k]=1;return;}
      int mid=(l+r)/2;
      build(k*2,l,mid);build(k*2+1,mid+1,r);
      update(k,l,r,mid);
    }
    inline void pushdown(int k,int l,int r,int mid)
    {
      if(tagfull[k])
      {
        trle[k*2]=trri[k*2]=trmx[k*2]=mid-l+1;tagfull[k*2]=true;tagclear[k*2]=false;
        trle[k*2+1]=trri[k*2+1]=trmx[k*2+1]=r-mid;tagfull[k*2+1]=true;tagclear[k*2+1]=false;
        tagfull[k]=false;
      }
      if(tagclear[k])
      {
        trle[k*2]=trri[k*2]=trmx[k*2]=trle[k*2+1]=trri[k*2+1]=trmx[k*2+1]=0;
        tagclear[k*2]=tagclear[k*2+1]=true;tagfull[k*2]=tagfull[k*2+1]=false;
        tagclear[k]=false;
      }
    }
    inline void full(int k,int l,int r,int x,int y)
    {
      if(l>=x&&r<=y)
      {
        trle[k]=trri[k]=trmx[k]=r-l+1;tagfull[k]=true;tagclear[k]=false;return;
      }
      int mid=(l+r)/2;pushdown(k,l,r,mid);
      if(x<=mid)  full(k*2,l,mid,x,y);
      if(y>mid)  full(k*2+1,mid+1,r,x,y);
      update(k,l,r,mid);
    }
    inline void clear(int k,int l,int r,int x,int y)
    {
      if(l>=x&&r<=y)
      {
        trle[k]=trri[k]=trmx[k]=0;tagclear[k]=true;tagfull[k]=false;return;
      }
      int mid=(l+r)/2;pushdown(k,l,r,mid);
      if(x<=mid)  clear(k*2,l,mid,x,y);
      if(y>mid)  clear(k*2+1,mid+1,r,x,y);
      update(k,l,r,mid);
    }
    inline int find(int k,int l,int r,int x)
    {
      int mid=(l+r)/2; 
      pushdown(k,l,r,mid);
      if(trle[k]>=x)  
      {
        clear(1,1,n,l,l+x-1);return l;
      }
      else if(trmx[k*2]>=x)  return find(k*2,l,mid,x);
      else if(trri[k*2]+trle[k*2+1]>=x)  
      {
        int temp=mid-trri[k*2]+1;
        clear(1,1,n,mid-trri[k*2]+1,mid-trri[k*2]+x);
        return temp;
      }
      else if(trmx[k*2+1]>=x)  return find(k*2+1,mid+1,r,x);
      else if(trri[k]>=x)  
      {
        clear(1,1,n,r-x+1,r);return r-x+1;
      }
    }
    int main()
    {
      //freopen("a.in","r",stdin);
      n=R(),m=R();  
      build(1,1,n);int op,a,b;
      while(m--)  
      {
        op=R();
        if(op==1)
        {
          a=R();
          if(trmx[1]<a)  printf("0
    ");
          else printf("%d
    ",find(1,1,n,a));
        }
        if(op==2)
        {
          a=R(),b=R();
          full(1,1,n,a,a+b-1);
        }
      }
      return 0;
    }
     
  • 相关阅读:
    poj 1860 Currency Exchange(最短路径的应用)
    poj 2965 The Pilots Brothers' refrigerator
    zoj 1827 the game of 31 (有限制的博弈论)
    poj 3295 Tautology (构造法)
    poj 1753 Flip Game(枚举)
    poj 2109 (贪心)
    poj 1328(贪心)
    Qt 对单个控件美化
    Qt 4基础
    Bash Shell
  • 原文地址:https://www.cnblogs.com/AseanA/p/7634221.html
Copyright © 2011-2022 走看看