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

Codeforces 35E(区间更新)

时间:2015-08-21 13:32:27      阅读:125      评论:0      收藏:0      [点我收藏+]

标签:

题意:要建n个高楼,给出了每个高楼的左右区间和高度,问最后所有的高楼的轮廓包括了哪些点。
题解:这题好坑,用了n种姿势了还是一直wa,后来才直到必须加输入输出文件那句话才能过。。。用线段树存维护区间内最大值也就是高度,左右区间到1e9所以要离散化。因为维护的是每一段的最大值而不是点,所以划分左右子区间那里要把mid到mid+1也归到右子区间里。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
const int N = 100005;
int n, a[N << 1], h[N], l[N], r[N], hh;
int tree[N << 4], res[N << 3][2];
map<int, int> mp;

void pushdown(int k) {
    if (tree[k]) {
        tree[k * 2] = max(tree[k * 2], tree[k]);
        tree[k * 2 + 1] = max(tree[k * 2 + 1], tree[k]);
        tree[k] = 0;
    }
}

void modify(int k, int left, int right, int l1, int r1, int x) {
    if (l1 <= left && right <= r1) {
        tree[k] = max(tree[k], x);
        return;
    }
    pushdown(k);
    int mid = (left + right) / 2;
    if (l1 < mid)
        modify(k * 2, left, mid, l1, r1, x);
    if (r1 > mid)
        modify(k * 2 + 1, mid, right, l1, r1, x);
}

void query(int k, int left, int right, int l1, int r1) {
    if (left + 1 == right) {
        hh = tree[k];
        return;
    }
    pushdown(k);
    int mid = (left + right) / 2;
    if (l1 < mid)
        query(k * 2, left, mid, l1, r1);
    else
        query(k * 2 + 1, mid, right, l1, r1);
}

int main() {
    freopen("input.txt", "r", stdin);  
    freopen("output.txt", "w", stdout);
    scanf("%d", &n);
    memset(tree, 0, sizeof(tree));
    mp.clear();
    int cnt = 0;
    for (int i = 1; i <= n; i++) {
        scanf("%d%d%d", &h[i], &l[i], &r[i]);
        a[cnt++] = l[i];
        a[cnt++] = r[i];
    }
    sort(a, a + cnt);
    cnt = unique(a, a + cnt) - a;
    for (int i = 0; i < cnt; i++)
        mp[a[i]] = i;

    for (int i = 1; i <= n; i++)
        modify(1, 0, cnt - 1, mp[l[i]], mp[r[i]], h[i]);
    int num = 0, curh = 0;
    for (int i = 0; i < cnt - 1; i++) {
        query(1, 0, cnt - 1, i, i + 1);
        if (hh != curh) {
            res[num][0] = a[i];
            res[num++][1] = curh;
            res[num][0] = a[i];
            res[num++][1] = hh;
            curh = hh;
        }
    }
    if (curh) {
        res[num][0] = a[cnt - 1];
        res[num++][1] = curh;
        res[num][0] = a[cnt - 1];
        res[num++][1] = 0;
    }
    printf("%d\n", num);
    for (int i = 0; i < num; i++)
        printf("%d %d\n", res[i][0], res[i][1]);
    return 0;
}

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

Codeforces 35E(区间更新)

标签:

原文地址:http://blog.csdn.net/hyczms/article/details/47833087

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