您的位置:首页 > 其它

FZU 2187 回家种地(矩形面积并)

2015-08-20 19:12 274 查看

题意:

求的是只覆盖了一次的面积并是多少。

解析:

相对于普通的面积并来说,就是求cover==1cover==1的长度,去掉了cover>=1cover>=1的长度。

参考了网络上的做法,用sum维护当前区间cover>=1cover>=1的长度,single维护cover==1cover==1的长度。

其他地方和普通的面积并一模一样,只是在pushUp的时候稍微多了对single的维护而已

mymy codecode

[code]#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 __int64 ll;
const int maxn = (int)2e5 + 5;

struct Line {
    ll l, r, h, d;
    Line() {}
    Line(ll l, ll r, ll h, ll d) : l(l), r(r), h(h), d(d) {}
} line[maxn];

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

int n, m, tot;
ll X[maxn];

ll sum[maxn<<2], single[maxn<<2];
int cover[maxn<<2];

void build(int o, int L, int R) {
    sum[o] = single[o] = cover[o] = 0;
    if(L == R) return ;
    int M = (L + R)/2;
    build(lson);
    build(rson);
}

inline void pushUp(int o, int L, int R) {
    if(cover[o]) {
        sum[o] = X[R+1] - X[L];
        if(cover[o] == 1) single[o] = sum[o] - sum[ls] - sum[rs];
        else single[o] = 0;
    }else if(L == R) sum[o] = single[o] = 0;
    else {
        sum[o] = sum[ls] + sum[rs];
        single[o] = single[ls] + single[rs];
    }
}

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

int find(int x) {  
    int L = 0, R = tot-1; 
    while(L <= R) {
        int M = (L + R) >> 1;  
        if(X[M] == x) return M;
        if(X[M] < x) L = M + 1;
        else R = M - 1;
    }
    return -1;  
}

int main() {
    int T, cas = 1;
    int x1, y1, x2, y2;

    scanf("%d", &T);
    while(T--) {
        m = tot = 0;
        scanf("%d", &n);    
        for(int i = 0; i < n; i++) {
            scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
            line[m] = Line(x1, x2, y1, 1);
            X[m++] = x1;
            line[m] = Line(x1, x2, y2, -1);
            X[m++] = x2;
        }

        sort(X, X+m);
        tot = unique(X, X+m) - X;

        sort(line, line+m, cmp);
        build(1, 0, tot-1);

        ll ans = 0;
        int ql, qr;
        for(int i = 0; i < m; i++) {
            ql = find(line[i].l);
            qr = find(line[i].r) - 1;
            modify(1, 0, tot-1, ql, qr, line[i].d);
            ans += single[1] * (line[i+1].h - line[i].h);
        }
        printf("Case %d: %I64d\n", cas++, ans);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: