您的位置:首页 > 其它

ZOJ 3299 Fall the Brick(线段树区间更新)

2015-08-01 14:33 453 查看

题意:

有n块板砖从天而降,底下有了m块木板来挡,每块板砖长度为1单位。

现在题目给出连续板砖的范围还有木板的范围与高度,问最后每块木板上有几块板砖。

解析:

这题想了挺久的最后终于搞定了。

线段树的区间更新问题。

由于lil_i和rir_i比较大(0<=li<ri<=30000000)(0 <= l_i < r_i <= 30000000),首先考虑到的是对左右边界进行离散化。然后先按照木板从低到高进行排序,然后对区间进行染色。

然后再把所有的砖块放上去,对区间进行更新,维护一个addv的懒惰标记,代表这个区间被覆盖了多少层。

最后进行到一次直到叶子节点的总查询得到最终答案。

总复杂度O((n+m+tot)log2n)O((n+m+tot)log_2n)

注意:

这题对内存的要求比较高,开小了会re,开大了会mle。

mymy codecode

[code]#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ls (o<<1)
#define rs (o<<1|1)
#define lson ls, L, M
#define rson rs, M+1, R
using namespace std;
typedef long long ll;

const int N = 100005;
struct Node {
    int ll, rr, lid, rid;
    int h, id;
} brick
, board
;

int n, m, tot;
int id[N*6];
ll length[N*6], ans
;

bool cmp(Node a, Node b) {
    return a.h < b.h;
}

void discrete() {
    sort(id, id+tot);
    tot = unique(id, id+tot) - id;
    for(int i = 1; i <= n; i++) {
        brick[i].lid = lower_bound(id, id+tot, brick[i].ll) - id;
        brick[i].rid = lower_bound(id, id+tot, brick[i].rr) - id - 1;
    }
    for(int i = 1; i <= m; i++) {
        board[i].lid = lower_bound(id, id+tot, board[i].ll) - id;
        board[i].rid = lower_bound(id, id+tot, board[i].rr) - id - 1;
    }
    for(int i = 0; i < tot-1; i++) {
        length[i] = id[i+1] - id[i];
    }
}

ll color[N*12], addv[N*12];
void build(int o, int L, int R) {
    color[o] = addv[o] = 0;
    if(L == R) return ;
    int M = (L + R)/2;
    build(lson);
    build(rson);
}

void pushDown(int o) {
    if(color[o]) {
        color[ls] = color[rs] = color[o];
        color[o] = 0;
    }
    if(addv[o]) {
        addv[ls] += addv[o]; addv[rs] += addv[o];
        addv[o] = 0;
    }
}

void setColor(int o, int L, int R, int ql, int qr, int val) {
    if(ql <= L && R <= qr) {
        color[o] = val;
        return ;
    }
    pushDown(o);
    int M = (L + R)/2;
    if(ql <= M) setColor(lson, ql, qr, val);
    if(qr > M) setColor(rson, ql, qr, val);
}

void modify(int o, int L, int R, int ql, int qr) {
    if(ql <= L && R <= qr) {
        addv[o]++;
        return ;
    }
    pushDown(o);
    int M = (L + R)/2;
    if(ql <= M) modify(lson, ql, qr);
    if(qr > M) modify(rson, ql, qr);
}

void query(int o, int L, int R) {
    if(L == R) {
        if(color[o])
            ans[color[o]] += addv[o]*length[L];
        return ;
    }
    pushDown(o);
    int M = (L + R)/2;
    query(lson);
    query(rson);
}

int main() {
    while(scanf("%d%d", &n, &m) != EOF) {
        tot = 0;
        for(int i = 1; i <= n; i++) {
            scanf("%d%d", &brick[i].ll, &brick[i].rr);
            id[tot++] = brick[i].ll;
            id[tot++] = brick[i].rr;
        }

        for(int i = 1; i <= m; i++) {
            scanf("%d%d%d", &board[i].ll, &board[i].rr, &board[i].h);
            id[tot++] = board[i].ll;
            id[tot++] = board[i].rr;
            board[i].id = i;
        }

        discrete();
        int end = tot-2;
        build(1, 0, end);

        sort(board+1, board+m+1, cmp);
        for(int i = 1; i <= m; i++)
            setColor(1, 0, end, board[i].lid, board[i].rid, board[i].id);
        for(int i = 1; i <= n; i++)
            modify(1, 0, end, brick[i].lid, brick[i].rid);

        memset(ans, 0, sizeof(ans));
        query(1, 0, end);

        for(int i = 1; i <= m; i++)
            printf("%lld\n", ans[i]);
        puts("");
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: