题意:有N个房间,M次操作。有两种操作(1)"1 a",表示找到连续的长度为a的空房间,如果有多解,优先左边的,即表示入住。(2)"2 b len",把起点为b长度的len的房间清空,即退房。三个数组分别记录 lsum区间左值 rsum区间右值 sum区间最大值。
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const double eps = 1e-;
template <class T>
inline bool scan_d(T &ret)
{
char c;
int sgn;
if(c=getchar(),c==EOF) return ;
while(c!='-'&&(c<''||c>'')) c=getchar();
sgn=(c=='-')?-:;
ret=(c=='-')?:(c-'');
while(c=getchar(),c>=''&&c<='') ret=ret*+(c-'');
ret*=sgn;
return ;
} const int maxn = 5e4+;
int lv[maxn<<],rv[maxn<<], setv[maxn<<]; //lv,rv数组可有可无,lsum rsum数组已经包含了他们的意义。
int lsum[maxn<<],rsum[maxn<<],sum[maxn<<]; void push_up(int l,int r,int pos)
{
lv[pos] = lv[pos<<];
rv[pos] = rv[pos<<|];
lsum[pos] = lsum[pos<<];
rsum[pos] = rsum[pos<<|];
sum[pos] = max(sum[pos<<],sum[pos<<|]);
sum[pos] = max(sum[pos],rsum[pos<<]+lsum[pos<<|]);
int mid = (l + r) >> ;
if (rv[pos<<] ==lv[pos<<|] && !rv[pos<<])
{
if (lsum[pos<<] == mid - l + )
lsum[pos] += lsum[pos<<|];
if (rsum[pos<<|] == r - mid)
rsum[pos] += rsum[pos<<];
sum[pos] = max(sum[pos],rsum[pos<<]+lsum[pos<<|]);
}
} void push_down(int l,int r,int pos)
{
if (~setv[pos])
{
int mid = (l + r) >> ;
setv[pos<<] = setv[pos<<|] = setv[pos];
lv[pos<<] = setv[pos];
lv[pos<<|] = setv[pos];
rv[pos<<] = setv[pos];
rv[pos<<|] = setv[pos];
lsum[pos<<] = (setv[pos] ? : (mid-l+));
rsum[pos<<] = (setv[pos] ? : (mid-l+));
lsum[pos<<|] = (setv[pos] ? : (r-mid));
rsum[pos<<|] = (setv[pos] ? : (r-mid));
sum[pos<<] = (setv[pos] ? : (mid-l+));
sum[pos<<|] = (setv[pos] ? : (r-mid));
setv[pos] = -;
}
} void build (int l,int r,int pos)
{
if (l == r)
{
rv[pos] = lv[pos] = ;
sum[pos] = lsum[pos] = rsum[pos] = ;
return;
}
int mid = (l + r) >> ;
build(l,mid,pos<<);
build(mid+,r,pos<<|);
push_up(l,r,pos);
} void update(int l,int r,int pos,int ua,int ub,int val)
{
if (ua <= l && ub >= r)
{
setv[pos] = val;
lv[pos] = val;
rv[pos] = val;
lsum[pos] = (val ? : (r-l+));
rsum[pos] = (val ? : (r-l+));
sum[pos] = (val ? : (r-l+));
return;
}
int mid = (l + r) >> ;
push_down(l,r,pos);
if (ua <= mid)
update(l,mid,pos<<,ua,ub,val);
if (ub > mid)
update(mid+,r,pos<<|,ua,ub,val);
push_up(l,r,pos);
} int query(int l,int r,int pos,int x)
{
if (lsum[pos] >= x)
{
return l; }
int mid = (l + r) >> ;
push_down(l,r,pos);
if (sum[pos<<] >= x)
return query(l,mid,pos<<,x);
/*else if (rsum[pos<<1]&&rsum[pos<<1] + lsum[pos<<1|1] >= x) //注释部分是错误的,,看起来很像但是不一样的
return query(l,mid,pos<<1,rsum[pos<<1]);*/
else if (rsum[pos<<] + lsum[pos<<|] >= x)
return mid+-rsum[pos<<];
else
return query(mid+,r,pos<<|,x);
} int main(void)
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int n,q;
while (~scanf ("%d%d",&n,&q))
{
build(,n,);
memset(setv,-,sizeof(setv));
for (int i = ; i < q; i++)
{
int op,x,y;
scanf ("%d",&op);
if (op == )
{
scanf ("%d",&x);
if (sum[] < x)
{
printf("0\n");
continue;
}
int p = query(,n,,x);
printf("%d\n",p);
update(,n,,p,p+x-,);
}
else
{
scanf ("%d%d",&x,&y);
update(,n,,x,y+x-,);
}
}
}
return ;
}