• POJ 3667 Hotel(线段树+区间合并)


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

    题意:

    有N个房间,M次操作。有两种操作(1)"1a",表示找到连续的长度为a的空房间,如果有多解,优先左边的,即表示入住。(2)"2 b len",把起点为b长度的len的房间清空,即退房。

    思路:

    区间合并的线段树题。

    其实如果单点更新和区间更新做得多了的话,区间合并也就不难了。

    对于这道题,我们用线段树维护三个值,从左端开始的连续空房间数,从右边开始的连续空房间数,以及整个区间内最大的连续空房间数。

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<vector>
      6 #include<stack>
      7 #include<queue>
      8 #include<cmath>
      9 #include<map>
     10 #include<set>
     11 using namespace std;
     12 typedef long long ll;
     13 const int INF = 0x3f3f3f3f;
     14 const int maxn=50000+5;
     15 
     16 int n, m;
     17 
     18 struct node //维护从左端开始的最大连续空房间,从右端开始的最大连续空房间,总的最大连续空房间
     19 {
     20     int l,r;
     21     int ls,rs,sum;
     22 }t[maxn<<2];
     23 
     24 int lazy[maxn<<2];
     25 
     26 
     27 void PushUp(int o)
     28 {
     29     t[o].ls=t[o<<1].ls;
     30     t[o].rs=t[o<<1|1].rs;
     31     int mid=(t[o].l+t[o].r)>>1;
     32     if(t[o].ls==mid-t[o].l+1)  t[o].ls+=t[o<<1|1].ls;  //如果左半部分都是空房间,那么可以与右半部分的左边空房间连起来
     33     if(t[o].rs==t[o].r-mid)   t[o].rs+=t[o<<1].rs;
     34     t[o].sum=max(max(t[o<<1].sum,t[o<<1|1].sum),t[o<<1].rs+t[o<<1|1].ls);
     35 }
     36 
     37 void PushDonw(int o)
     38 {
     39     if(lazy[o]!=-1)
     40     {
     41         lazy[o<<1]=lazy[o<<1|1]=lazy[o];
     42         if(lazy[o])   //为1的话要将该区间置满
     43         {
     44             t[o<<1].ls=t[o<<1].rs=t[o<<1].sum=0;
     45             t[o<<1|1].ls=t[o<<1|1].rs=t[o<<1|1].sum=0;
     46         }
     47         else  //为0的话要将该区间置空
     48         {
     49             t[o<<1].ls=t[o<<1].rs=t[o<<1].sum=t[o<<1].r-t[o<<1].l+1;
     50             t[o<<1|1].ls=t[o<<1|1].rs=t[o<<1|1].sum=t[o<<1|1].r-t[o<<1|1].l+1;
     51         }
     52         lazy[o]=-1;
     53     }
     54 }
     55 
     56 void build(int l, int r, int o)
     57 {
     58     lazy[o]=-1;
     59     t[o].l=l;
     60     t[o].r=r;
     61     t[o].ls=t[o].rs=t[o].sum=r-l+1;
     62     if(l==r)  return;
     63     int mid=(l+r)>>1;
     64     build(l,mid,o<<1);
     65     build(mid+1,r,o<<1|1);
     66 }
     67 
     68 
     69 void update(int ql, int qr, int l, int r, int flag, int o)
     70 {
     71     if(ql<=l && qr>=r)
     72     {
     73         if(flag) t[o].ls=t[o].rs=t[o].sum=0;
     74         else t[o].ls=t[o].rs=t[o].sum=r-l+1;
     75         lazy[o]=flag;
     76         return;
     77     }
     78     PushDonw(o);
     79     int mid=(l+r)>>1;
     80     if(ql<=mid)  update(ql,qr,l,mid,flag,o<<1);
     81     if(qr>mid)   update(ql,qr,mid+1,r,flag,o<<1|1);
     82     PushUp(o);
     83 }
     84 
     85 int query(int l, int r, int num, int o)
     86 {
     87     if(l==r)  return l;
     88     PushDonw(o);
     89     int mid=(l+r)>>1;
     90     if(t[o<<1].sum>=num)  return query(l,mid,num,o<<1);
     91     else if(t[o<<1].rs+t[o<<1|1].ls>=num)  return mid-t[o<<1].rs+1;
     92     else return query(mid+1,r,num,o<<1|1);
     93 }
     94 
     95 int main()
     96 {
     97     //freopen("in.txt","r",stdin);
     98     scanf("%d%d",&n,&m);
     99     build(1,n,1);
    100     while(m--)
    101     {
    102         int op;
    103         scanf("%d",&op);
    104         if(op==1)
    105         {
    106             int x;
    107             scanf("%d",&x);
    108             if(t[1].sum<x)  {puts("0");continue;}
    109             int pos=query(1,n,x,1);
    110             printf("%d
    ",pos);
    111             update(pos,pos+x-1,1,n,1,1);
    112         }
    113         else
    114         {
    115             int s,t;
    116             scanf("%d%d",&s,&t);
    117             update(s,s+t-1,1,n,0,1);
    118         }
    119     }
    120     return 0;
    121 }
  • 相关阅读:
    JavaScript中的闭包
    正则表达式(括号)、[中括号]、{大括号}的区别
    写出将字符串中的数字转换为整型的方法,如:“as31d2v”->312,并写出相应的单元测试,正则去掉非数值、小数点及正负号外的字符串
    正则替换实现字符串链接每4位用“-”连接成新的字符串
    memcache搭建
    MySQL优化
    网络优化
    JDK配置及tomcat部署
    oracle中增加pga和sga
    sudo用法
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7452142.html
Copyright © 2020-2023  润新知