也是很久之前的题目,一直没做

做完之后觉得基本的离散化和扫描线还是不难的,由于本题要离散x点的坐标,最后要计算被覆盖的x轴上的长度,所以不能用普通的建树法,建树建到r-l==1的时候就停止,表示某段而不是某点,同样,左子树和右子树要变成 L MID , MID R

比如1-4子树就是 1-2,2-4。。。2-4再分成2-3,3-4.

然后就是经典的扫描线用法,对下边设标记为1,上边设标记为-1,每次求得x轴被覆盖的长度,乘以和下一条线段的距离(即矩形的高)即可

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid,r
using namespace std;
const int N = 210;
double d[N*N];
int flag[N*N];
int n;
double X[N];
struct node
{
double l,r,y,f;
bool operator < (const node &rhs) const{
return y<rhs.y;
}
}seg[N];
void build(int rt,int l,int r)
{
flag[rt]=0;
d[rt]=0;
if (r-l<=1){
return;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
}
void up(int rt,int l,int r)
{
if (flag[rt]>0){
d[rt]=X[r]-X[l];
}
else
{
if (r-l==1) d[rt]=0;
else d[rt]=d[rt<<1]+d[rt<<1|1];
}
}
void cover(int L,int R,double v,int rt,int l,int r)
{
//cout<<l<<" @@@ "<<r<<endl;
if (L<=l && r<=R){
flag[rt]+=v;
up(rt,l,r);
return;
}
if (r-l<=1) return;
int mid=(l+r)>>1;
if (R<=mid) cover(L,R,v,lson);
else
if (L>mid) cover(L,R,v,rson);
else
{
cover(L,R,v,lson);
cover(L,R,v,rson);
}
up(rt,l,r);
}
int main()
{
double xa,ya,xb,yb;
int kase=0;
while (scanf("%d",&n)!=EOF)
{
if (n==0) break;
int cnt=1;
for (int i=1;i<=n;i++){
scanf("%lf%lf%lf%lf",&xa,&ya,&xb,&yb);
X[cnt]=xa;
seg[cnt++]=(node){xa,xb,ya,1.0};
X[cnt]=xb;
seg[cnt++]=(node){xa,xb,yb,-1.0};
}
sort(X+1,X+cnt);
sort(seg+1,seg+cnt);
int tmp=1;
for (int i=2;i<cnt;i++){
if(X[i]!=X[i-1]){
X[++tmp]=X[i];
}
}
build(1,1,tmp);
double ans=0;
for (int i=1;i<cnt-1;i++){
//cout<<seg[i].l<<" .. "<<seg[i].r<<endl;
int l1=lower_bound(X+1,X+1+tmp,seg[i].l)-X;
int l2=lower_bound(X+1,X+1+tmp,seg[i].r)-X;
//cout<<l1<<" "<<l2<<" "<<X[l1]<<" "<<X[l2]<<endl;
cover(l1,l2,seg[i].f,1,1,tmp);
//cout<<d[1]<<endl;
ans+=d[1]*(seg[i+1].y-seg[i].y);
//cout<<ans<<endl;
}
printf("Test case #%d\n",++kase);
printf("Total explored area: %.2lf\n",ans);
puts("");
}
return 0;
}

  

HDU 1542 线段树离散化+扫描线 平面面积计算的更多相关文章

  1. hdu 1542 线段树之扫描线之面积并

    点击打开链接 题意:给你n个矩形,求它们的面积,反复的不反复计算 思路:用线段树的扫描线完毕.将X坐标离散化后,从下到上扫描矩形,进行各种处理,看代码凝视把 #include <stdio.h& ...

  2. hdu 1542 线段树扫描(面积)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  3. hdu1542 矩形面积并(线段树+离散化+扫描线)

    题意: 给你n个矩形,输入每个矩形的左上角坐标和右下角坐标. 然后求矩形的总面积.(矩形可能相交). 题解: 前言: 先说说做这道题的感受: 刚看到这道题顿时就懵逼了,几何 烂的渣渣.后来从网上搜题解 ...

  4. 【POJ 2482】 Stars in Your Window(线段树+离散化+扫描线)

    [POJ 2482] Stars in Your Window(线段树+离散化+扫描线) Time Limit: 1000MS   Memory Limit: 65536K Total Submiss ...

  5. hdu 1542 线段树+扫描线 学习

    学习扫描线ing... 玄学的东西... 扫描线其实就是用一条假想的线去扫描一堆矩形,借以求出他们的面积或周长(这一篇是面积,下一篇是周长) 扫描线求面积的主要思想就是对一个二维的矩形的某一维上建立一 ...

  6. POJ 1177/HDU 1828 picture 线段树+离散化+扫描线 轮廓周长计算

    求n个图矩形放下来,有的重合有些重合一部分有些没重合,求最后总的不规则图型的轮廓长度. 我的做法是对x进行一遍扫描线,再对y做一遍同样的扫描线,相加即可.因为最后的轮廓必定是由不重合的线段长度组成的, ...

  7. POJ1151Atlantis 矩形面积并[线段树 离散化 扫描线]

    Atlantis Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 21734   Accepted: 8179 Descrip ...

  8. POJ 1151Atlantis 矩形面积并[线段树 离散化 扫描线]

    Atlantis Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 21734   Accepted: 8179 Descrip ...

  9. hdu1542线段树+离散化+扫描线

    参考博客: http://blog.csdn.net/xingyeyongheng/article/details/8927732 总的来说就是用一条(假想的)线段去平行x轴从下往上扫描,扫描的过程中 ...

随机推荐

  1. Law of large numbers and Central limit theorem

    大数定律 Law of large numbers (LLN) 虽然名字是 Law,但其实是严格证明过的 Theorem weak law of large number (Khinchin's la ...

  2. ubuntu 文件操作

    linux的文件目录是一棵目录树,默认起始位置在主文件夹(/home/city),里面有若干子文件(视频.图片.下载.桌面等) 一.文件路径(目录操作) 1.绝对路径:从根目录/写起,完整的.详细的描 ...

  3. jQuery序列化表单 serialize() serializeArray()(非常重要)

    https://m.2cto.com/kf/201412/361303.html 2014-12-15 1.serialize()方法 描述:序列化表单内容为字符串,用于Ajax请求. 格式:var ...

  4. 一个前端博主的nginx+php+mysql的环境搭建

    这几天天某的公司给了在下一个需求,让我修改一个后端大佬用PHP写的一个官网,虽然说修改的内容还是很简单,但是毕竟之前还是没接触过PHP,于是开始了漫长的爬坑之旅,话不多说,这次就给大家介绍一下我配置安 ...

  5. 条款01:视C++为一个语言联邦

    C++由四部分组成: 1)C. 2)Object-Oriented C++.classes,封装,多态,动态绑定(virtual函数) 3)Template C++.泛型编程. 4)STL. 对于内置 ...

  6. 6专题总结-动态规划dynamic programming

    专题6--动态规划 1.动态规划基础知识 什么情况下可能是动态规划?满足下面三个条件之一:1. Maximum/Minimum -- 最大最小,最长,最短:写程序一般有max/min.2. Yes/N ...

  7. 「USACO08JAN」电话线Telephone Lines

    传送门 Luogu 解题思路 考虑二分,每次把大于二分值的边的权设为1,小于等于的设为0,如果最短路<=k则可行,记得判无解 细节注意事项 咕咕咕 参考代码 #include <algor ...

  8. C 常用库函数memset,编译器宏定义assert

    一. 总览 1.1库函数 函数名 头文件 功能 原型 说明 syslog syslog.h 记录至系统记录(日志) void    syslog(int, const char *, ...) __p ...

  9. Java并发编程之并发简介

    操作系统中同时执行多个程序原因: 1.资源利用率:系统资源及硬件资源.当一个程序再等待另一个程序时,可以运行另一个程序,可提高资源利用率. 2.公平性:多个程序对计算机上的资源理论上具有同等的使用权. ...

  10. gym 101911

    A. Coffee Break 题意:每天有m小时,你喝咖啡需要花一小时,你想在n个时刻都喝过一次咖啡,老板规定连续喝咖啡的间隔必须是d以上,求最少需要多少天才能喝够n次咖啡,并输出每个时刻第几天喝. ...