求长度为K的连续区间的左端点的最小值
check in 的时候,先查寻出左端点r,然后插入线段[r, r+D-1]
check out 的时候,直接删除线段[X, X+D-1]
要使用lazy标记,否则TLE
代码写的有点。。。。
/*===============================================================
* Copyright (C) 2012 All rights reserved.
*
* file: 3667_Hotel.cpp
* author: ivapple
* date: 2012-09-22
* description:
*
* update log:
*
================================================================*/
#include <cstdlib>
#include <cstdio>
#include <iostream>
#define out(x) (cout<<#x<<": "<<x<<endl)
#define FOR(i,s,t) for(i=s; i<t; i++)
using namespace std;
template<class T>void show(T a, int n){int i; for(i=0;i<n;i++)cout<<a[i]<<" ";cout<<endl;}
template<class T>void show(T a, int r, int l){int i; for(i=0;i<r;i++)show(a[i],l);cout<<endl;}
const int kMaxNum = 50000;
struct SegTree
{
int s, e;
int lc, rc;
int lv, rv, maxv;
int cover;
}tree[4*kMaxNum];
int id = -1;
int Max(int a, int b, int c)
{
a = a>b?a:b;
return c>a?c:a;
}
void BuildTree(int l, int r)
{
int root = ++id;
int mid;
tree[root].s = l;
tree[root].e = r;
tree[root].lv = r-l+1;
tree[root].rv = r-l+1;
tree[root].maxv = r-l+1;
if (l < r)
{
mid = (l+r)/2;
tree[root].lc = id+1;
BuildTree(l, mid);
tree[root].rc = id+1;
BuildTree(mid+1,r);
}
}
int InsertDown(int root)
{
int lc, rc;
lc = tree[root].lc;
rc = tree[root].rc;
if (lc)
{
tree[lc].cover = 1;
tree[lc].lv = 0;
tree[lc].rv = 0;
tree[lc].maxv = 0;
}
if (rc)
{
tree[rc].cover = 1;
tree[rc].lv = 0;
tree[rc].rv = 0;
tree[rc].maxv = 0;
}
tree[root].cover = 0;
}
int DeleteDown(int root)
{
int lc, rc;
lc = tree[root].lc;
rc = tree[root].rc;
if (lc)
{
tree[lc].cover = -1;
tree[lc].lv = tree[lc].e-tree[lc].s+1;
tree[lc].rv = tree[lc].e-tree[lc].s+1;
tree[lc].maxv = tree[lc].e-tree[lc].s+1;
}
if (rc)
{
tree[rc].cover = -1;
tree[rc].lv = tree[rc].e-tree[rc].s+1;
tree[rc].rv = tree[rc].e-tree[rc].s+1;
tree[rc].maxv = tree[rc].e-tree[rc].s+1;
}
tree[root].cover = 0 ;
}
int Query(int root, int len)
{
int lc, rc;
if (tree[root].lv >= len)
return tree[root].s;
else
{
if (tree[root].maxv < len)
return 0;
else
{
lc = tree[root].lc;
rc = tree[root].rc;
if (tree[lc].maxv >= len)
{
if (tree[root].cover == 1)
InsertDown(root);
if (tree[root].cover == -1)
DeleteDown(root);
return Query(lc, len);
}
else
{
if (tree[lc].rv+tree[rc].lv >= len)
return tree[lc].e-tree[lc].rv+1;
else
{
if (tree[rc].maxv >= len)
{
if (tree[root].cover == 1)
InsertDown(root);
if (tree[root].cover == -1)
DeleteDown(root);
return Query(rc, len);
}
}
}
}
}
}
int Update(int root)
{
int lc = tree[root].lc;
int rc = tree[root].rc;
int mid = (tree[root].s + tree[root].e)/2;
tree[root].lv = tree[lc].lv + ((tree[lc].lv+tree[lc].s-1)>=mid?tree[rc].lv:0);
tree[root].rv = tree[rc].rv + ((tree[rc].e-tree[rc].rv)<=mid?tree[lc].rv:0);
int tmp = tree[lc].rv + tree[rc].lv;
int max = Max(tree[root].lv, tree[root].rv, tmp);
tree[root].maxv = Max(tree[lc].maxv, tree[rc].maxv, max);
}
void Insert(int root, int l, int r)
{
if (l<=tree[root].s&&tree[root].e<=r)
{
tree[root].cover = 1;
tree[root].lv = 0;
tree[root].rv = 0;
tree[root].maxv = 0;
return;
}
if (tree[root].cover == 1)
InsertDown(root);
if (tree[root].cover == -1)
DeleteDown(root);
int mid, lc, rc;
lc = tree[root].lc;
rc = tree[root].rc;
mid = (tree[root].s+tree[root].e)/2;
if (l <= mid)
Insert(lc, l, r);
if (r > mid)
Insert(rc, l, r);
Update(root);
}
void Delete(int root, int l, int r)
{
if (l<=tree[root].s&&tree[root].e<=r)
{
tree[root].cover = -1;
tree[root].lv = tree[root].e-tree[root].s+1;
tree[root].rv = tree[root].e-tree[root].s+1;
tree[root].maxv = tree[root].e-tree[root].s+1;
return;
}
if (tree[root].cover == 1)
InsertDown(root);
if (tree[root].cover == -1)
DeleteDown(root);
int mid, lc, rc;
lc = tree[root].lc;
rc = tree[root].rc;
mid = (tree[root].s+tree[root].e)/2;
if (l <= mid)
Delete(lc, l, r);
if (r > mid)
Delete(rc, l, r);
Update(root);
}
int N, M;
int main()
{
int i;
int op, D, X;
int r;
#ifndef ONLINE_JUDGE
freopen("test.txt", "r", stdin);
#endif
scanf("%d%d", &N, &M);
BuildTree(1, N);
for (i=0; i<M; i++)
{
scanf("%d",&op);
if (op == 1)
{
scanf("%d", &D);
r = Query(0, D);
if (r == 0)
printf("0\n");
else
{
printf("%d\n", r);
Insert(0, r, r+D-1);
}
}
if (op == 2)
{
scanf("%d%d", &X, &D);
Delete(0, X, X+D-1);
}
}
return 0;
}