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

HDU1542 矩形面积并 扫描线段树

时间:2019-08-10 12:22:35      阅读:69      评论:0      收藏:0      [点我收藏+]

标签:targe   扫描线   tps   acm   opera   efi   type   stream   矩形   

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542

题意:二维平面有n个平行于坐标轴的的矩形,要算矩形面积并

有一个讲的很好的博客:https://blog.csdn.net/u013480600/article/details/22548393

线段树是按叶节点来一个个维护的,一堆浮点数是不能直接维护的,需要离散化来维护。

要注意我们线段树中每个叶节点(控制区间[L,L])不是指X[L]坐标,而是指区间[X[L],X[L+1]].线段树中其他节点控制的区间[L,R],也是指的x坐标轴的第L个区间到第R个区间的范围,也就是X[L]到X[R+1]坐标的范围.

简而言之,维护的是区间。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mid (l+r)/2
using namespace std;
typedef long long ll;
const int maxn=1000+10;
double dat[4*maxn];
int lazy[maxn];
double b[maxn];
struct edge{
    double l,r,h;
    int cnt;
    friend bool operator < (edge x,edge y){
        return x.h<y.h;
    }
}e[maxn];
void pushup(int a,int l,int r){
    if(lazy[a])    dat[a]=b[r+1]-b[l];
    else    dat[a]=dat[a<<1]+dat[a<<1|1];
}
void update(int a,int l,int r,int s,int t,int k){
    if(s>r || t<l)    return;
    if(s<=l && r<=t){
        lazy[a]+=k;
        pushup(a,l,r);
        return;
    }
    if(s<=mid)    update(a<<1,l,mid,s,t,k);
    if(t>mid)    update(a<<1|1,mid+1,r,s,t,k);
    pushup(a,l,r);
}
int main(){
    int n;
    int T=0;
    while(~scanf("%d",&n)){
        memset(dat,0,sizeof(dat));
        memset(lazy,0,sizeof(lazy));
        memset(b,0,sizeof(b));
        memset(e,0,sizeof(e));
        if(n==0)    return 0;
        T++;
        int p=0,num=0;
        for(int i=1;i<=n;i++){
            double x1,x2,y1,y2;
            scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
            e[++p].l=x1;
            e[p].r=x2;
            e[p].h=y1;
            e[p].cnt=1;
            e[++p].l=x1;
            e[p].r=x2;
            e[p].h=y2; 
            e[p].cnt=-1;
            b[++num]=x1;
            b[++num]=x2;
        }
        sort(e+1,e+1+p);
        sort(b+1,b+1+num);
        int m=unique(b+1,b+1+num)-b-1;
        double ans=0;
        for(int i=1;i<p;i++){
            int l=lower_bound(b+1,b+m,e[i].l)-b;
            int r=lower_bound(b+1,b+m,e[i].r)-b;
            update(1,1,m-1,l,r-1,e[i].cnt);//记住r-1是关键,维护的是区间,一共有m-1个区间 
            ans+=dat[1]*(e[i+1].h-e[i].h);
        }
        printf("Test case #%d\n",T);
        printf("Total explored area: %.2lf\n\n",ans);
    }
    return 0;
}

 

HDU1542 矩形面积并 扫描线段树

标签:targe   扫描线   tps   acm   opera   efi   type   stream   矩形   

原文地址:https://www.cnblogs.com/qingjiuling/p/11330889.html

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