Codeforces 35E(区间更新)

来源:互联网 发布:java中setscale 编辑:程序博客网 时间:2024/05/18 03:21

题意:要建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;}
0 0
原创粉丝点击