poj 3667 Hotel

来源:互联网 发布:js json数组排序 编辑:程序博客网 时间:2024/05/16 19:36

题意:在一个酒店里有一排房间从1到N标号,游客们要来住店,对于这些房间有两种操作,一种是查询有没有连续的n间房间,有的话就返回最小的房间号并标记入住,没有就返回0,另一种操作就是取消连续的房间a到b的入住。

线段树的基本题型,利用区间的合并就可解决。对于线段树中的每个节点需要记录区间范围[L,R],区间从左起连续的房间数lsum,区间从右边起连续的房间数rsum,区间最大的连续房间数sum,还有就是懒惰标记d(其中1表示入住,0表示取消入住,-1表示没有更新消息)。

代码:

#include <iostream>#include <cstdio>using namespace std;#define maxn 55555struct node{      int l, r, lsum, rsum, sum, d;}v[maxn*4];void build (int l, int r, int n){      v[n].l = l;      v[n].r = r;      v[n].lsum = v[n].rsum = v[n].sum = r-l+1;      v[n].d = -1;      if (l==r)            return ;      int mid = (v[n].l + v[n].r) >> 1;      build(l, mid, n<<1);      build(mid+1, r, n<<1|1);}void pushdown(int n){      if (v[n].d!=-1)      {            int t = v[n].r-v[n].l+1;            v[n<<1].lsum = v[n<<1].rsum = v[n<<1].sum = v[n].d?0:t-(t>>1);            v[n<<1|1].lsum = v[n<<1|1].rsum = v[n<<1|1].sum = v[n].d?0:(t>>1);            v[n<<1].d = v[n<<1|1].d = v[n].d;            v[n].d = -1;      }}void pushup(int n){      v[n].lsum = v[n<<1].lsum;      v[n].rsum = v[n<<1|1].rsum;      int t = v[n].r-v[n].l+1;      if (v[n].lsum == t-(t>>1))            v[n].lsum += v[n<<1|1].lsum;      if (v[n].rsum == t>>1)            v[n].rsum += v[n<<1].rsum;      v[n].sum = max( v[n<<1].sum, max( v[n<<1|1].sum, v[n<<1].rsum+v[n<<1|1].lsum ) );}void update(int l, int r, int d, int n){      if (l<=v[n].l && v[n].r<=r)      {            v[n].lsum = v[n].rsum = v[n].sum = d?0:r-l+1;            v[n].d = d;            return ;      }      pushdown(n);      int mid = (v[n].l+v[n].r)>>1;      if (r<=mid)            update(l, r, d, n<<1);      else if (l>mid)            update(l, r, d, n<<1|1);      else      {            update(l, mid, d, n<<1);            update(mid+1, r, d, n<<1|1);      }      pushup(n);}int query(int w, int n){      pushdown(n);      int mid = (v[n].l+v[n].r)>>1;      if (v[n<<1].sum>=w)            return query(w, n<<1);      else if (v[n<<1].rsum+v[n<<1|1].lsum>=w)            return mid-v[n<<1].rsum+1;      else            return query(w, n<<1|1);}int main(){      int n, m, op, a, b;      while (~scanf("%d%d", &n, &m))      {            build(1, n, 1);            while (m--)            {                  scanf("%d", &op);                  if (op==1)                  {                        scanf("%d", &a);                        if (v[1].sum<a)                              printf("0\n");                        else                        {                              int t = query(a, 1);                              printf("%d\n", t);                              update(t, a+t-1, 1, 1);                        }                  }                  else                  {                        scanf("%d%d", &a, &b);                        update(a, a+b-1, 0, 1);                  }            }      }      return 0;}


原创粉丝点击