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\n");

151                     continue;

152                 }

153                 int p = query(1,n,1,x);

154                 printf("%d\n",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 }

 

你可能感兴趣的:(poj)