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

HDU1542矩形面积并

时间:2016-09-15 15:00:16      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:

取出纵向边按x坐标排序,在y方向上建立线段树。

每次查询当前有效长度len,ans += len*(x[i]-x[i-1]); 其中len为T[rt].len;

查询完毕后更新y方向上线段树,入边+1, 出边-1。

 

技术分享
#include<bits/stdc++.h>
using namespace std;
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
typedef long long ll;
struct L{
    double x, y1, y2;
    int d;
    L(){}
    L(double x, double y1, double y2, int d): x(x), y1(y1), y2(y2), d(d){}
};
L line[500];
bool cmp(L A, L B){
    return A.x < B.x;
}
double y[500];

struct Node{
    int d;
    double len;
};
Node T[500<<3];
void init(){
    memset(T, 0, sizeof(T));
}
void pushup(int rt, int l, int r){
    if(T[rt].d)
        T[rt].len = y[r]-y[l-1];
    else
        T[rt].len = l == r? 0 : T[rt<<1].len+T[rt<<1|1].len;
}
void update(int L, int R, int d, int l, int r, int rt){
    if(L <= l&&r <= R){
        T[rt].d += d;
        pushup(rt, l , r);
        return ;
    }
    int m = (l+r)>>1;
    if(L <= m) update(L, R, d, lson);
    if(R > m) update(L, R, d, rson);
    pushup(rt, l, r);
}

int main(){
    int n, ca = 1;
    double x1, y1, x2, y2;
    while(scanf("%d", &n), n){
        for(int i = 0; i < n; i++){
            scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
            line[i*2] = L(x1, y1, y2, 1);
            line[i*2+1] = L(x2, y1, y2, -1);
            y[i*2] = y1, y[i*2+1] = y2;
        }
        sort(line, line+2*n, cmp);
        sort(y, y+2*n);

        init();
        double ans = 0, lastx = line[0].x;
        for(int i = 1; i < 2*n; i++){
            if(i&&line[i].x != line[i-1].x)
                ans += (line[i].x-line[i-1].x)*T[1].len;
            int l = lower_bound(y, y+2*n, line[i].y1)-y+1, r = lower_bound(y, y+2*n, line[i].y2)-y;
            if(l <= r)
                update(l, r, line[i].d, 1, 2*n, 1);
        }
        printf("Test case #%d\n", ca++);
        printf("Total explored area: %.2f\n\n", ans);
    }
    return 0;
}
View Code

 

无pushdown()函数,每条线段只存一次。d表示被覆盖的次数,len表示至少被覆盖一次的合法长度。详见pushup()函数。

ans += T[1].len*(x[i]-x[i-1]);

 

 

求面积交:方法同求面积并,外加len2表示至少被覆盖两次的合法长度,ans += T[1].len2*(x[i]-x[i-1]);

 

求周长并:方法同面积并,扫描两次,分别沿x方向和y方向,每次加上  更新前后T[1].len的差值的绝对值。

HDU1542矩形面积并

标签:

原文地址:http://www.cnblogs.com/dirge/p/5874748.html

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