Poj 3667 Hotel

来源:互联网 发布:淘宝产品卖点怎么写 编辑:程序博客网 时间:2024/05/16 17:53

题目链接:http://poj.org/problem?id=3667

本题也是线段树区间合并问题。和上一题LCIS类似。

题意:1 a:询问是不是有连续长度为a的空房间,有的话住进最左边
2 a b:将[a,a+b-1]的房间清空
思路:记录区间中最长的空房间

#include <iostream>#include <stdlib.h>#include <stdio.h>using namespace std;#define Maxn 50005#define lx (x<<1)#define rx ((x<<1)|1)#define MID ((l + r)>>1)int A[Maxn];//记录连续空房间的最大个数int midSum[Maxn<<2];int leftSum[Maxn<<2];int rightSum[Maxn<<2];//标记是否被覆盖int cover[Maxn<<2];void pushDown(int l,int r,int x){    if(cover[x]!=-1)    {        int m = (r - l + 1);        cover[lx] = cover[rx] = cover[x];        //被占用        if(cover[x] == 1)        {            midSum[lx] = leftSum[lx] = rightSum[lx] = 0;            midSum[rx] = leftSum[rx] = rightSum[rx] = 0;        }        //未被占用        else        {            midSum[lx] = leftSum[lx] = rightSum[lx] = m - (m>>1);            midSum[rx] = leftSum[rx] = rightSum[rx] = (m>>1);        }cover[x] = -1;    }}void pushUp(int l,int r,int x){    int m = r - l + 1;    leftSum[x] = leftSum[lx];    rightSum[x] = rightSum[rx];if(leftSum[x] == m-(m>>1)) leftSum[x] += leftSum[rx];if(rightSum[x] == (m >> 1)) rightSum[x] += rightSum[lx];midSum[x] = max(leftSum[rx] + rightSum[lx],max(midSum[lx],midSum[rx]));}void build(int l,int r,int x){    cover[x] = -1;    midSum[x] = leftSum[x] = rightSum[x] =  (r - l + 1);    if(l == r) return;    build(l,MID,lx);    build(MID+1,r,rx);}void update(int L,int R,int d,int l,int r,int x){    if(L<=l && r<=R)    {        cover[x] = d;        if(d == 0) midSum[x] = leftSum[x] = rightSum[x] = r-l+1;        else midSum[x] = leftSum[x] = rightSum[x] = 0;        return;    }    pushDown(l,r,x);    if(L<=MID) update(L,R,d,l,MID,lx);    if(MID+1<=R) update(L,R,d,MID+1,r,rx);    pushUp(l,r,x);}int query(int w,int l,int r,int x){    if (l == r) return l;    pushDown(l,r,x);    if(w<=midSum[lx]) return query(w,l,MID,lx);    else if(w<=rightSum[lx] + leftSum[rx]) return (MID - rightSum[lx] + 1);    else return query(w,MID+1,r,rx);}int main(){    #ifndef ONLINE_JUDGE        freopen("in.txt","r",stdin);    #endif    int n,m;    int op;    int d,x;    scanf(" %d %d",&n,&m);    build(1,n,1);    for(int i=0;i<m;i++)    {        scanf(" %d",&op);        if(op == 1)        {            scanf(" %d",&d);            if(midSum[1]<d) puts("0");            else            {                int p = query(d,1,n,1);                printf("%d\n",p);                update(p,p+d-1,1,1,n,1);            }        }        else        {            scanf(" %d %d",&x,&d);            update(x,x+d-1,0,1,n,1);        }    }    return 0;}


原创粉丝点击