zoukankan      html  css  js  c++  java
  • poj3667---Hotel 线段树区间合并,区间更新

    题意:有N个房间,M次操作。有两种操作(1)"1 a",表示找到连续的长度为a的空房间,如果有多解,优先左边的,即表示入住。(2)"2 b len",把起点为b长度的len的房间清空,即退房。三个数组分别记录   lsum区间左值       rsum区间右值       sum区间最大值。

      1 #include <set>
      2 #include <map>
      3 #include <cmath>
      4 #include <ctime>
      5 #include <queue>
      6 #include <stack>
      7 #include <cctype>
      8 #include <cstdio>
      9 #include <string>
     10 #include <vector>
     11 #include <cstdlib>
     12 #include <cstring>
     13 #include <iostream>
     14 #include <algorithm>
     15 using namespace std;
     16 typedef unsigned long long ull;
     17 typedef long long ll;
     18 const int inf = 0x3f3f3f3f;
     19 const double eps = 1e-8;
     20 template <class T>
     21 inline bool scan_d(T &ret)
     22 {
     23     char c;
     24     int sgn;
     25     if(c=getchar(),c==EOF) return 0;
     26     while(c!='-'&&(c<'0'||c>'9')) c=getchar();
     27     sgn=(c=='-')?-1:1;
     28     ret=(c=='-')?0:(c-'0');
     29     while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
     30     ret*=sgn;
     31     return 1;
     32 }
     33 
     34 const int maxn = 5e4+10;
     35 int lv[maxn<<2],rv[maxn<<2], setv[maxn<<2];          //lv,rv数组可有可无,lsum rsum数组已经包含了他们的意义。
     36 int lsum[maxn<<2],rsum[maxn<<2],sum[maxn<<2];
     37 
     38 void push_up(int l,int r,int pos)
     39 {
     40     lv[pos] = lv[pos<<1];
     41     rv[pos] = rv[pos<<1|1];
     42     lsum[pos] = lsum[pos<<1];
     43     rsum[pos] = rsum[pos<<1|1];
     44     sum[pos] = max(sum[pos<<1],sum[pos<<1|1]);
     45     sum[pos] = max(sum[pos],rsum[pos<<1]+lsum[pos<<1|1]);
     46     int mid = (l + r) >> 1;
     47     if (rv[pos<<1] ==lv[pos<<1|1] && !rv[pos<<1])
     48     {
     49         if (lsum[pos<<1] == mid - l + 1)
     50             lsum[pos] += lsum[pos<<1|1];
     51         if (rsum[pos<<1|1] == r - mid)
     52             rsum[pos] += rsum[pos<<1];
     53         sum[pos] = max(sum[pos],rsum[pos<<1]+lsum[pos<<1|1]);
     54     }
     55 }
     56 
     57 void push_down(int l,int r,int pos)
     58 {
     59     if (~setv[pos])
     60     {
     61         int mid = (l + r) >> 1;
     62         setv[pos<<1] = setv[pos<<1|1] = setv[pos];
     63         lv[pos<<1] = setv[pos];
     64         lv[pos<<1|1] = setv[pos];
     65         rv[pos<<1] = setv[pos];
     66         rv[pos<<1|1] = setv[pos];
     67         lsum[pos<<1] = (setv[pos] ? 0 : (mid-l+1));
     68         rsum[pos<<1] = (setv[pos] ? 0 : (mid-l+1));
     69         lsum[pos<<1|1] = (setv[pos] ? 0 : (r-mid));
     70         rsum[pos<<1|1] = (setv[pos] ? 0 : (r-mid));
     71         sum[pos<<1] = (setv[pos] ? 0 : (mid-l+1));
     72         sum[pos<<1|1] = (setv[pos] ? 0 : (r-mid));
     73         setv[pos] = -1;
     74     }
     75 }
     76 
     77 void build (int l,int r,int pos)
     78 {
     79     if (l == r)
     80     {
     81         rv[pos] = lv[pos] = 0;
     82         sum[pos] = lsum[pos] = rsum[pos] = 1;
     83         return;
     84     }
     85     int mid = (l + r) >> 1;
     86     build(l,mid,pos<<1);
     87     build(mid+1,r,pos<<1|1);
     88     push_up(l,r,pos);
     89 }
     90 
     91 void update(int l,int r,int pos,int ua,int ub,int val)
     92 {
     93     if (ua <= l && ub >= r)
     94     {
     95         setv[pos] = val;
     96         lv[pos] = val;
     97         rv[pos] = val;
     98         lsum[pos] = (val ? 0 : (r-l+1));
     99         rsum[pos] = (val ? 0 : (r-l+1));
    100         sum[pos] =  (val ? 0 : (r-l+1));
    101         return;
    102     }
    103     int mid = (l + r) >> 1;
    104     push_down(l,r,pos);
    105     if (ua <= mid)
    106         update(l,mid,pos<<1,ua,ub,val);
    107     if (ub > mid)
    108         update(mid+1,r,pos<<1|1,ua,ub,val);
    109     push_up(l,r,pos);
    110 }
    111 
    112 int query(int l,int r,int pos,int x)
    113 {
    114     if (lsum[pos] >= x)
    115     {
    116         return l;
    117 
    118     }
    119     int mid = (l + r) >> 1;
    120     push_down(l,r,pos);
    121     if (sum[pos<<1] >= x)
    122          return query(l,mid,pos<<1,x);
    123     /*else if (rsum[pos<<1]&&rsum[pos<<1] + lsum[pos<<1|1] >= x)          //注释部分是错误的,,看起来很像但是不一样的
    124         return query(l,mid,pos<<1,rsum[pos<<1]);*/
    125     else if (rsum[pos<<1] + lsum[pos<<1|1] >= x)
    126         return mid+1-rsum[pos<<1];
    127     else
    128         return query(mid+1,r,pos<<1|1,x);
    129 }
    130 
    131 int main(void)
    132 {
    133     #ifndef ONLINE_JUDGE
    134     freopen("in.txt","r",stdin);
    135     #endif
    136     int n,q;
    137     while (~scanf ("%d%d",&n,&q))
    138     {
    139         build(1,n,1);
    140         memset(setv,-1,sizeof(setv));
    141         for (int i = 0; i < q; i++)
    142         {
    143             int op,x,y;
    144             scanf ("%d",&op);
    145             if (op == 1)
    146             {
    147                 scanf ("%d",&x);
    148                 if (sum[1] < x)
    149                 {
    150                     printf("0
    ");
    151                     continue;
    152                 }
    153                 int p = query(1,n,1,x);
    154                 printf("%d
    ",p);
    155                 update(1,n,1,p,p+x-1,1);
    156             }
    157             else
    158             {
    159                 scanf ("%d%d",&x,&y);
    160                 update(1,n,1,x,y+x-1,0);
    161             }
    162         }
    163     }
    164     return 0;
    165 }
  • 相关阅读:
    wpf 用c#代码给img指定uri
    c 指针作为出参
    wpf获得系统毫秒数
    绑定元素的长宽(Canvas的子类自动伸展)
    PB与COM之关于创建COM,MTS, and COM+组件(1)
    ASA破解密码
    遭遇奸商(显卡篇)
    “启动Word时提示出错,只能用安全模式才能打开”的解决方法
    PowerSocket对象与HostName
    制做集成SATA驱动的XP安装盘
  • 原文地址:https://www.cnblogs.com/oneshot/p/3998519.html
Copyright © 2011-2022 走看看