HDU 1542 Atlantics 线段树+离散化扫描
将 x 轴上的点进行离散化,扫描线沿着 y 轴向上扫描
每次添加一条边不断找到当前状态有效边的长度 , 根据这个长度和下一条边形成的高度差得到一块合法的矩形的面积
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm> using namespace std; const int MAX=+;
int flag[MAX<<];//记录某个区间的下底边个数
double sum[MAX<<];//记录某个区间的下底边总长度
double x[MAX];//对x进行离散化,否则x为浮点数且很大无法进行线段树 struct Seg{//线段
double x1,x2,y;
int d;
Seg(){}
Seg(double x1 , double x2 , double y , int d):x1(x1),x2(x2),y(y),d(d){}
bool operator<(const Seg &a)const{
return y<a.y;
}
}s[MAX]; void updateCur(int n,int left,int right){
if(flag[n]) sum[n] = x[right+] - x[left];//表示该区间整个线段长度可以作为底边
else if(left == right) sum[n] = ;//叶子结点则底边长度为0(区间内线段长度为0)
else sum[n] = sum[n<<] + sum[n<<|];
} void update(int o , int l , int r , int s , int t , int d){
if(s<=l && r<=t){//该区间是当前扫描线段的一部分,则该区间下底边总长以及上下底边个数差更新
flag[o] += d;//更新底边相差差个数
updateCur(o , l , r);//更新底边长
return;
}
int mid = (l + r)>> , ls = o<< , rs = o<<|;
if(mid >= s) update(ls , l , mid , s , t , d);
if(mid+ <= t) update(rs , mid+ , r , s , t , d);
updateCur(o , l , r);
} int bin_search(double key , int n){
int l = , r = n-;
while(l<=r){
int mid = (l+r) >>;
if(x[mid] == key) return mid;
if(x[mid] > key) r=mid-;
else l=mid+;
}
return -;
} int main()
{
// freopen("a.in" , "r" , stdin);
int n,cas=;
double x1,x2,y1,y2;
while(scanf("%d" , &n) , n){
int k=;
for(int i=;i<n;++i){
cin>>x1>>y1>>x2>>y2;
x[k]=x1;
s[k++]=Seg(x1,x2,y1,);
x[k]=x2;
s[k++]=Seg(x1,x2,y2,-);
}
sort(x,x+k);
sort(s,s+k);
int t = unique(x , x+k) - x;
double ans=; for(int i=;i<k;++i){//扫描线段
int pos1 = bin_search(s[i].x1 , t);
/*
这里因为是把它理解成合法线段,所以最右端第 i 个点 , 对应第 i - 1条边
同样道理,在updateCur中,计算有效线段长度时 , 需要x[r+1]
*/
int pos2 = bin_search(s[i].x2 , t)-;
update( , , t- , pos1 , pos2 , s[i].d);//扫描线段时更新底边长度和底边相差个数
ans += sum[]*(s[i+].y-s[i].y);//新增加面积
}
printf("Test case #%d\nTotal explored area: %.2lf\n\n",++cas,ans);
}
return ;
}
HDU 1542 Atlantics 线段树+离散化扫描的更多相关文章
- POJ 1151 / HDU 1542 Atlantis 线段树求矩形面积并
题意:给出矩形两对角点坐标,求矩形面积并. 解法:线段树+离散化. 每加入一个矩形,将两个y值加入yy数组以待离散化,将左边界cover值置为1,右边界置为2,离散后建立的线段树其实是以y值建的树,线 ...
- HDU 1542 Atlantis (线段树 + 扫描线 + 离散化)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- HDU 1542 - Atlantis - [线段树+扫描线]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...
- hdu 1542 Atlantis(线段树,扫描线)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- HDU 4325-Flowers(线段树+离散化)
题意: 给出每个花开花的时间段,每询问一个时间点输出该时间点开花的数量 分析: 线段树的区间更新,单点查询,但发现时间很大,没法存区间,就想到了离散化. 离散化就是把要处理的数据统一起来重新标号. # ...
- HDU 1542 Atlantis(线段树面积并)
描述 There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. S ...
- POJ 1177/HDU 1828 picture 线段树+离散化+扫描线 轮廓周长计算
求n个图矩形放下来,有的重合有些重合一部分有些没重合,求最后总的不规则图型的轮廓长度. 我的做法是对x进行一遍扫描线,再对y做一遍同样的扫描线,相加即可.因为最后的轮廓必定是由不重合的线段长度组成的, ...
- hdu 1542 Atlantis (线段树扫描线)
大意: 求矩形面积并. 枚举$x$坐标, 线段树维护$[y_1,y_2]$内的边是否被覆盖, 线段树维护边时需要将每条边挂在左端点上. #include <iostream> #inclu ...
- Atlantis HDU - 1542 (线段树扫描线)
There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some ...
随机推荐
- Objective-C程序
创建: 2018/01/17 完成: 2018/01/19 对象(object)与信息 信息式 声明实例变量 id obj; 向对象变量发送信息 [obj msg] //这就是信息式 例: [ ...
- 源码阅读之ArrayList(JDK8)
ArrayList概述 ArrayList是一个的可变数组的实现,实现了所有可选列表操作,并允许包括 null 在内的所有元素.每个ArrayList实例都有一个容量,该容量是指用来存储列表元素的数组 ...
- RabbitMQ学习之Work Queues(2)
目录: 轮询调度(Round-robin dispatching):即依次分配分配任务给worker. 消息答复(Message acknowledgement):在consumer处理完之后,进行消 ...
- Java对象简单实用(计算器案例)
对 Java中的对象与属性,方法的使用,简单写了个案例 import java.util.Scanner; class Calculste { int a; //定义两个整数 int b; Strin ...
- MySql学习笔记(1)-安装
一.安装环境 操作系统:win7 64ibt MySql版本:5.7.10.0 二.安装过程 1.点击Add 2.选择需要安装的组件 3.Excute 4.Next 5.Next 6.进入服务器配置 ...
- Angular——路由参数
基本介绍 在控制中注入$routeParams可以获取传递的参数 区别对比 angular中的路由是指#之后的内容,包括之后的?,而在之前的http地址中我们习惯性的将?放在前面 具体使用 1.形参 ...
- STA之Concepts (1)
Static Timing Analysis is one of the many techniques available to verify the timing of a digital des ...
- 十年后我不会log,还是活的很好啊
混迹于互联网也一两年了,出于喜爱与生活压力依然会从事很久.迟迟不写博客,大概是觉得知识与经验积累在笔记上时不时看看就好了,而实际情况是笔记很少翻,遇到问题搜博客和百度依然是首选,故开通博客记录自己工作 ...
- lsb_release No LSB modules are available
lsb_release 提示: No LSB modules are available 执行: sudo apt-get install lsb-core
- ls 命令还能这么玩?看一下这 20 个实用范例
Linux中一个基本命令是ls.没有这个命令,我们会在浏览目录条目时会遇到困难.这个命令必须被每个学习Linux的人知道. ls是什么 ls命令用于列出文件和目录.默认上,他会列出当前目录的内容.带上 ...