扫描线,线段树,离散化——HDU - 1542

Posted helman

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了扫描线,线段树,离散化——HDU - 1542相关的知识,希望对你有一定的参考价值。

题目含义

每一行给出两个点,代表一个矩形的左下角端点和右上角端点

要你求出这些矩形覆盖坐标轴的整个面积

题目分析

用平行x轴的扫描线扫描整个图形,得到很多长宽不同的矩形,求出面积再相加

将每个矩形的面积记作 len(x)*len(y)

每个len(x)我们通过加减每个点的x左右坐标,通过线段树求sum[1]得到

每个len(y)我们通过这个点与下一个点的y坐标的差得到

所以我们要把所有点按y轴大小排序,并且记录每个点的左右x轴坐标

注意:这里用的线段树sum【l,r】不是指区间【l,r】的和,而是指X.l和X.r的差

题目代码

#include<stdio.h>
#include<iostream>
#include<vector>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=1e5+7;
typedef long long LL;
vector<double>v;
int n;
double x1,y1,x2,y2;
double len[maxn<<2];
int cov[maxn<<2];
struct node
    double y,x1,x2;
    int k;
rem[maxn];
int getid(double x)
    return lower_bound(v.begin(),v.end(),x)-v.begin()+1;

bool cmp(node a,node b)
    return a.y<b.y;

void pushup(int l,int r,int rt)
    if(cov[rt]>0)len[rt]=v[r]-v[l-1];
    else if(l==r)len[rt]=0;
    else len[rt]=len[rt<<1]+len[rt<<1|1];

void updata(int l,int r,int rt,int ll,int rr,int k)
    if(ll<=l&&r<=rr)
        cov[rt]+=k;
        pushup(l,r,rt);
        return;
    
    int mid=(l+r)>>1;
    if(ll<=mid)updata(l,mid,rt<<1,ll,rr,k);
    if(rr>mid)updata(mid+1,r,rt<<1|1,ll,rr,k);
    pushup(l,r,rt);

int main()
    int ce=0;
    while(scanf("%d",&n)&&n)
        memset(len,0,sizeof(len));
        memset(cov,0,sizeof(cov));
        v.clear();
        int cnt=0;
        for(int i=0;i<n;i++)
            scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
            v.push_back(x1);
            v.push_back(x2);
            rem[++cnt].x1=x1,rem[cnt].x2=x2,rem[cnt].y=y1,rem[cnt].k=1;
            rem[++cnt].x1=x1,rem[cnt].x2=x2,rem[cnt].y=y2,rem[cnt].k=-1;
        
        sort(v.begin(),v.end());
        v.erase(unique(v.begin(),v.end()),v.end());
        sort(rem+1,rem+1+cnt,cmp);
        double ans=0;
        for(int i=1;i<cnt;i++)
            updata(1,cnt,1,getid(rem[i].x1),getid(rem[i].x2)-1,rem[i].k);
            ans+=len[1]*(rem[i+1].y-rem[i].y);
        
        printf("Test case #%d\nTotal explored area: %.2f\n\n",++ce,ans);
    
    return 0;

 

以上是关于扫描线,线段树,离散化——HDU - 1542的主要内容,如果未能解决你的问题,请参考以下文章

hdu1542 Atlantis (线段树+扫描线+离散化)

HDU - 1542 扫描线入门+线段树离散化

扫描线,线段树,离散化——HDU - 1542

HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)

HDU 1542.Atlantis-线段树求矩形面积并(离散化扫描线/线段树)-贴模板

HDU1542-Atlantis离散化&线段树&扫描线个人认为很全面的详解