• poj 3667 Hotel 线段树


    题目链接

    这个题需要维护三个变量, 一个是区间最大连续长度, 一个是最长前缀, 一个是最长后缀。 需要注意的就是查询的时候, 先查左区间是否满足, 然后应该查左区间和右区间交界处是否满足, 这里要看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);
                }
            }
        }
    }
  • 相关阅读:
    hdu 2527:Safe Or Unsafe(数据结构,哈夫曼树,求WPL)
    hdu 2019:数列有序!(数据结构,直接插入排序+折半插入排序)
    hdu 3791:二叉搜索树(数据结构,二叉搜索树 BST)
    hdu 3336:Count the string(数据结构,串,KMP算法)
    hdu 1022:Train Problem I(数据结构,栈,递归,dfs)
    hdu 2141:Can you find it?(数据结构,二分查找)
    hdu 1232:畅通工程(数据结构,树,并查集)
    hdu 2025:查找最大元素(水题,顺序查找)
    hdu 2857:Mirror and Light(计算几何,点关于直线的对称点,求两线段交点坐标)
    hdu 1174:爆头(计算几何,三维叉积求点到线的距离)
  • 原文地址:https://www.cnblogs.com/yohaha/p/5028139.html
Copyright © 2020-2023  润新知