POJ 3667 Hotel 线段树 区间合并(成段更新)

来源:互联网 发布:折翼天使源码论坛 编辑:程序博客网 时间:2024/05/08 04:03
//POJ 3667 Hotel 线段树 区间合并(成段更新)/*题目大意:有n间房子,有两种操作:1 a:询问是不是有连续长度为a的空房间,有的话住进最左边2 a b:将[a,a+b-1]的房间清空思路:记录区间中最长的空房间 ,线段树操作:update:区间替换 query:询问满足条件的最左端点 ,线段树每个节点记录 3个参数 :lsum :左端开始的空余量 ;rsum :右端开始的空余量 ;msum : 最大空余量(可能在中间)*/#include<stdio.h>#define N 50005#define lson rt<<1,l,mid#define rson rt<<1|1,mid+1,rint lsum[N<<2],rsum[N<<2],msum[N<<2];int add[N<<2];int n,m;int Max(int x,int y){    return x>y?x:y;}void pushup(int rt,int m){    lsum[rt] = lsum[rt<<1];    rsum[rt] = rsum[rt<<1|1];    if(lsum[rt] == m-(m>>1)) lsum[rt] += lsum[rt<<1|1];    if(rsum[rt] == (m>>1)) rsum[rt] += rsum[rt<<1];    msum[rt] = Max(rsum[rt<<1] + lsum[rt<<1|1],Max(msum[rt<<1],msum[rt<<1|1]));}void pushdown(int rt,int m){    if(add[rt] != -1){        add[rt<<1] = add[rt<<1|1] = add[rt];        lsum[rt<<1] = rsum[rt<<1] = msum[rt<<1] = add[rt] ? 0 : m-(m>>1);        lsum[rt<<1|1] = rsum[rt<<1|1] = msum[rt<<1|1] = add[rt] ? 0 : (m>>1);        add[rt] = -1;    }}void build(int rt,int l,int r){    lsum[rt] = rsum[rt] = msum[rt] = r-l+1;    add[rt] = -1;    if(l == r) return;    int mid = (l + r) >> 1;    build(lson);    build(rson);}int query(int rt,int l,int r,int w){    if(l == r)    return l;    pushdown(rt,r-l+1);    int mid = (l + r) >> 1;    if(msum[rt<<1] >= w)        return query(lson,w);    else if(rsum[rt<<1] + lsum[rt<<1|1] >= w)        return mid-rsum[rt<<1]+1;    else        return query(rson,w);}void update(int rt,int l,int r,int L,int R,int w){    if(L <= l && R >= r){        lsum[rt] = rsum[rt] = msum[rt] = w ? 0 :r-l+1;        add[rt] = w;;        return;    }    pushdown(rt,r-l+1);    int mid = (l  + r) >> 1;    if(L <= mid) update(lson,L,R,w);    if(R > mid ) update(rson,L,R,w);    pushup(rt,r-l+1);}int main(){    int i;    int op,a,b,c;    while(scanf("%d %d",&n,&m)!=EOF){        build(1,1,n);        for(i = 1; i <= m; ++i){            scanf("%d",&op);            if(op == 1){                scanf("%d",&c);                if(msum[1] < c)                    puts("0");                else{                    int res = query(1,1,n,c);                    printf("%d\n",res);                    update(1,1,n,res,res+c-1,1);                }            }            else{                scanf("%d %d",&a,&b);                update(1,1,n,a,a+b-1,0);            }        }    }    return 0;}

原创粉丝点击