poj 3667

原创 2016年08月29日 22:29:15
#include <stdio.h>

#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1

const int maxn = 50000;

int n, mNum, op, a, b;
int sum[maxn*3], lsum[maxn*3], rsum[maxn*3], cover[maxn*3];

void BuildTree(int l, int r, int rt)
{
    cover[rt] = -1;
    lsum[rt] = rsum[rt] = sum[rt] = r-l+1;
    if (l == r)
        return ;
    
    int m = (l+r)>>1;
    BuildTree(lson);
    BuildTree(rson);
}/* BuildTree */

void PushDown(int rt, int k)
{
    if (cover[rt] != -1)
    {   /* Lazy Tag */
        cover[rt<<1] = cover[rt<<1|1] = cover[rt];
        lsum[rt<<1] = rsum[rt<<1] = sum[rt<<1] = cover[rt] ? 0:(k-(k>>1)); 
        lsum[rt<<1|1] = rsum[rt<<1|1] = sum[rt<<1|1] = cover[rt] ? 0:(k>>1);
        cover[rt] = -1;
    }
}/* PushDown */

int query(int w, int l, int r, int rt)
{
    if (l == r)
        return 1;
    
    PushDown(rt, r-l+1);    /* Push Down */
    
    int m = (l+r)>>1;
    if (sum[rt<<1] >= w)    /* 左连续区间长度 */ 
        return query(w, lson);
    else if (rsum[rt<<1]+lsum[rt<<1|1] >= w) /* 左区间后半部分与右区间左半部分长度 */ 
        return m-rsum[rt<<1]+1;
    else                    /* 右连续区间长度 */ 
        return query(w, rson);
}/* query */

int Max(int x, int y)
{
    return (x>y ? x:y);
}/* Max */

void PushUp(int rt, int k)
{
    lsum[rt] = lsum[rt<<1];   /* 左区间的左半部分 */ 
    rsum[rt] = rsum[rt<<1|1]; /* 右区间的右半部分 */ 
    
    if (lsum[rt] == k-(k>>1))
        lsum[rt] += lsum[rt<<1|1];
    if (rsum[rt] == k>>1)
        rsum[rt] += rsum[rt<<1];
    
    sum[rt] = Max(rsum[rt<<1]+lsum[rt<<1|1], Max(sum[rt<<1], sum[rt<<1|1]));
}/* PushUp */

void UpData(int L, int R, int c, int l, int r, int rt)
{
    if (L<=l && r<=R)
    {
        lsum[rt] = rsum[rt] = sum[rt] = c ? 0 : r-l+1;
        cover[rt] = c;
        
        return ;
    }/* End of If */
    
    PushDown(rt, r-l+1);    /* Push Down */
    
    int m = (l+r)>>1;
    if (L <= m)
        UpData(L, R, c, lson);
    if (R > m)
        UpData(L, R, c, rson);
    
    PushUp(rt, r-l+1);      /* Push Up */
}/* Updata */

int main()
{
    scanf("%d %d", &n, &mNum);
    
    BuildTree(1, n, 1); /* BuildTree */ 
    for (int i=1; i<=mNum; ++i)
    {
        scanf("%d", &op);
        if (op == 1)
        {   // Request
            scanf("%d", &a);
            if (sum[1] < a)
                printf("0\n");  /* No result */
            else
            {
                int pos = query(a, 1, n, 1);
                printf("%d\n", pos);
                UpData(pos, pos+a-1, 1, 1, n, 1);   /* UpData the interval */
            }
        }/* End of If */
        else
        {
            scanf("%d %d", &a, &b);
            UpData(a, a+b-1, 0, 1, n, 1);   /* UpData the interval */
        }
    }/* End of For */
    
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

[POJ3667]Hotel(线段树)

还有3分钟就该走啦!ATP抓紧时间发完最后一篇题解,到了比赛那边学校里肯定没有网,ATP就没有办法发题解了。。。...
  • FromATP
  • FromATP
  • 2016年11月18日 10:48
  • 145

POJ 3667 Hotel 【线段树+区间合并】

U - Hotel The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment an...

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

链接:http://poj.org/problem?id=3667 题意:一家旅馆,不断有人入住,退房。入住的人要求房号连续,退房是连续房号的房间退掉。 思路:线段树LAZY-TAG+区间合并。相比于...

POJ 3667 Hotel(线段树+区间合并+延迟标记)

延迟标记很重要,没有延迟标记,时间复杂度还是O(n)。 // // main.cpp // Richard // // Created by 邵金杰 on 16/8/21. // Copyr...

poj3667线段树区间合并

/* 本题是线段树区间合并 所谓区间合并我理解为父节点的某些值是由左孩子和右孩子的某些值合并而得到的 对这题,父节点最大连续可用区间可能是由左孩子最大可用右区间和右孩子的最大可用左区间合并得到的 *...

POJ - 3667 Hotel(线段树 区间合并 区间查询)

POJ 3667 Hotel(线段树 区间合并 区间查询) The cows are journeying north to Thunder Bay in Canada to gain cultura...

POJ 3667 Hotel 线段树区间合并

题意 一开始有1~n个空房间 对应2个操作  i)问有没有连续的长度为x的x间房如果有占满最左边的那个区间,输出这个区间的起点 ii)把区间x~x+y-1的房间清空 一个很明显的区间合并具体...

poj3667(线段树,区间合并)

地址:http://poj.org/problem?id=3667 Hotel Time Limit: 3000MS   Memory Limit: 65536K ...

POJ 3667 Hotel(线段树区间合并查询)

题目链接:点击打开链接 题意: 1 a:询问是否有连续长度为a的空房间,有的话选最左边 2 a b:将[a,a+b-1]区间的房间清空 思路:这类题目会询问区间中满足条件的连续最长区间,所以p...
  • ccDLlyy
  • ccDLlyy
  • 2017年08月01日 12:04
  • 82

poj 3667 最长空白段+查询最左连续段

Hotel 大体分析: 题意:从最左找连续空间,是否能找到。 解法:同poj1823。 //是1823的加强版,但是提交记录也是呵呵了。 //多的一个操作就是查询操...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:poj 3667
举报原因:
原因补充:

(最多只允许输入30个字)