码迷,mamicode.com
首页 > 其他好文 > 详细

poj 3667 Hotel 线段树

时间:2015-12-08 10:13:10      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:

题目链接

这个题需要维护三个变量, 一个是区间最大连续长度, 一个是最长前缀, 一个是最长后缀。 需要注意的就是查询的时候, 先查左区间是否满足, 然后应该查左区间和右区间交界处是否满足, 这里要看pre_max[rt<<1|1]+suf_max[rt<<1|1]是否大于等于给出的长度, 最后才是右区间。

#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, a, n) for(int i = a; i<n; i++)
#define ull unsigned long long
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int mod = 1e9+7;
const int inf = 1061109567;
const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
const int maxn = 50005;
int maxx[maxn<<2], pre_max[maxn<<2], suf_max[maxn<<2], cover[maxn<<2];
void pushUp(int rt, int m) {
    maxx[rt] = max(maxx[rt<<1], maxx[rt<<1|1]);
    pre_max[rt] = pre_max[rt<<1];
    suf_max[rt] = suf_max[rt<<1|1];
    if(maxx[rt<<1] == (m-(m>>1)))
        pre_max[rt] = pre_max[rt<<1] + pre_max[rt<<1|1];
    if(maxx[rt<<1|1] == (m>>1))
        suf_max[rt] = suf_max[rt<<1|1]+suf_max[rt<<1];
    maxx[rt] = max(maxx[rt], suf_max[rt<<1]+pre_max[rt<<1|1]);
}
void build(int l, int r, int rt) {
    maxx[rt] = pre_max[rt] = suf_max[rt] = r-l+1;
    cover[rt] = -1;
    if(l == r)
        return ;
    int m = l+r>>1;
    build(lson);
    build(rson);
}
void pushDown(int rt, int m) {
    if(~cover[rt]) {
        cover[rt<<1] = cover[rt<<1|1] = cover[rt];
        maxx[rt<<1] = pre_max[rt<<1] = suf_max[rt<<1] = cover[rt]*(m-(m>>1));
        pre_max[rt<<1|1] = suf_max[rt<<1|1] = maxx[rt<<1|1] = cover[rt]*(m>>1);
        cover[rt] = -1;
    }
}
void update(int L, int R, int l, int r, int rt, int val) {
    if(L<=l&&R>=r) {
        cover[rt] = val;
        maxx[rt] = suf_max[rt] = pre_max[rt] = val*(r-l+1);
        return ;
    }
    pushDown(rt, r-l+1);
    int m = l+r>>1;
    if(L<=m)
        update(L, R, lson, val);
    if(R>m)
        update(L, R, rson, val);
    pushUp(rt, r-l+1);
}
int query(int val, int l, int r, int rt) {
    if(l == r)
        return l;
    pushDown(rt, r-l+1);
    int m = l+r>>1;
    if(maxx[rt<<1]>=val)
        return query(val, lson);
    if(pre_max[rt<<1|1]+suf_max[rt<<1]>=val)
        return m-suf_max[rt<<1]+1;
    return query(val, rson);
}
int main()
{
    int n, m, sign, x, y;
    while(cin>>n>>m) {
        build(1, n, 1);
        while(m--) {
            scanf("%d", &sign);
            if(sign == 1) {
                scanf("%d", &x);
                if(maxx[1]<x) {
                    cout<<0<<endl;
                } else {
                    int pos = query(x, 1, n, 1);
                    cout<<pos<<endl;
                    update(pos, pos+x-1, 1, n, 1, 0);
                }
            } else {
                scanf("%d%d", &x, &y);
                update(x, y+x-1, 1, n, 1, 1);
            }
        }
    }
}

 

poj 3667 Hotel 线段树

标签:

原文地址:http://www.cnblogs.com/yohaha/p/5028139.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!