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 }
原文地址:https://www.cnblogs.com/oneshot/p/3998519.html