HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)
Atlantis
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 11551 Accepted Submission(s): 4906
The input file is terminated by a line containing a single 0. Don’t process it.
Output a blank line after each test case.
题目链接:HDU 1542
感觉难点就在如何用点树实现线段上的统计,首先这题是浮点数,肯定要离散化建树(我选的是对X坐标离散化),二分寻找下标当作区间[l,r]。
现在假设有两个区间段:1——2——3 与 3——4——5,但是如果用点树的方式进行更新对前面一个区间+1,后面一个区间-1,那会造成3这个点的覆盖次数变成0,但显然这两个区间在“段”上是连续的,这样更新肯定会出现问题,但是习惯上是写点树而不是段树,那只能对点修改一下,把更新区间的右端R减掉1,每个点表示这个点到后一个点的一段因此前面的两个区间变成了[1,2]与[3,4],这样在点上就不会出现重复的问题了,然后另外一点改动就是在pushup时直接向上传递不用pushdown。
举个例子
$$\begin{array}{c|lll}
{下标}&{0}&{1}&{2}&{3}&{4}&{5}\\
\hline
{实际值}&{3.3}&{9.8}&{12.1}&{19.8}&{24.9}&{33.3}\\
\end{array}$$
这样的一个坐标离散化这时候出现一个线段[9.8~12.1],然后对应离散化的是[1,2-1]即[1,1],但统计len的时候显然是用12.1-9.8=2.3,因此统计时要用X[R+1]-X[L]来作为长度即X[2]-X[1],那这看起来似乎跟前面的刻意把右端点改成R-1矛盾了……既然统计要R+1那前面干嘛要R-1,其实R-1为的是不影响线段树的区间覆盖,但是你是知道实际上要用R来算,由于统计时是不会影响区间覆盖的,因此要还原回去即R=(R-1)+1
代码:
#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
typedef pair<int,int> pii;
typedef long long LL;
const double PI=acos(-1.0);
const int N=110;
struct seg
{
int l,mid,r;
int cnt;
double len;
};
struct Line
{
double l,r,h,flag;
bool operator<(const Line &t)const
{
return h<t.h;
}
};
seg T[N<<3];
Line line[N<<1];
double xpos[N<<1]; inline void pushup(int k)
{
if(T[k].cnt)
T[k].len=xpos[T[k].r+1]-xpos[T[k].l];
else
{
if(T[k].l==T[k].r)
T[k].len=0;
else
T[k].len=T[LC(k)].len+T[RC(k)].len;
}
}
void build(int k,int l,int r)
{
T[k].l=l;
T[k].r=r;
T[k].mid=MID(l,r);
T[k].len=0.0;
T[k].cnt=0;
if(l==r)
return ;
build(LC(k),l,T[k].mid);
build(RC(k),T[k].mid+1,r);
}
void update(int k,int l,int r,int flag)
{
if(l<=T[k].l&&T[k].r<=r)
{
T[k].cnt+=flag;
pushup(k);
}
else
{
if(r<=T[k].mid)
update(LC(k),l,r,flag);
else if(l>T[k].mid)
update(RC(k),l,r,flag);
else
update(LC(k),l,T[k].mid,flag),update(RC(k),T[k].mid+1,r,flag);
pushup(k);
}
}
int main(void)
{
int n,i,q=1;
double xa,xb,ya,yb;
while (~scanf("%d",&n)&&n)
{
int cnt_line=0;
for (i=0; i<n; ++i)
{
scanf("%lf%lf%lf%lf",&xa,&ya,&xb,&yb);
xpos[cnt_line]=xa;
line[cnt_line]=(Line){xa,xb,ya,1};
++cnt_line;
xpos[cnt_line]=xb;
line[cnt_line]=(Line){xa,xb,yb,-1};
++cnt_line;
}
sort(xpos,xpos+cnt_line);//X轴坐标排序
sort(line,line+cnt_line);//线段排序 build(1,0,cnt_line); double res=0.0,dh;
int l,r;
for (i=0; i<cnt_line-1; ++i)
{
l=lower_bound(xpos,xpos+cnt_line,line[i].l)-xpos;
r=lower_bound(xpos,xpos+cnt_line,line[i].r)-xpos;
update(1,l,r-1,line[i].flag);
dh=line[i+1].h-line[i].h;
res+=dh*T[1].len;
}
printf("Test case #%d\nTotal explored area: %.2f\n\n",q++,res);
}
return 0;
}
HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)的更多相关文章
- 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 (线段树扫描线)
大意: 求矩形面积并. 枚举$x$坐标, 线段树维护$[y_1,y_2]$内的边是否被覆盖, 线段树维护边时需要将每条边挂在左端点上. #include <iostream> #inclu ...
- hdu 1542 Atlantis(线段树,扫描线)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]
题意:求矩形面积并 分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化! 把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区 ...
- POJ 1151 / HDU 1542 Atlantis 线段树求矩形面积并
题意:给出矩形两对角点坐标,求矩形面积并. 解法:线段树+离散化. 每加入一个矩形,将两个y值加入yy数组以待离散化,将左边界cover值置为1,右边界置为2,离散后建立的线段树其实是以y值建的树,线 ...
- HDU 1542 Atlantis(线段树面积并)
描述 There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. S ...
- hdu 4419 线段树 扫描线 离散化 矩形面积
//离散化 + 扫描线 + 线段树 //这个线段树跟平常不太一样的地方在于记录了区间两个信息,len[i]表示颜色为i的被覆盖的长度为len[i], num[i]表示颜色i 『完全』覆盖了该区间几层. ...
- POJ 1177 Picture(线段树 扫描线 离散化 求矩形并面积)
题目原网址:http://poj.org/problem?id=1177 题目中文翻译: 解题思路: 总体思路: 1.沿X轴离散化建树 2.按Y值从小到大排序平行与X轴的边,然后顺序处理 如果遇到矩形 ...
随机推荐
- Struts文件上传allowedTypes问题,烦人的“允许上传的文件类型”
Struts的文件上传问题,相信很多人都会使用allowedTypes参数来配置允许上传的文件类型,如下. <param name="allowedTypes"> im ...
- Groovy安装配置
一.介绍 Groovy是可以运行在 Java 平台上进行动态语言,使用方式基本与使用 Java 的方式相同,Groovy和java基本是可以实现无缝整合,它有以下一些特性: 是一个基于Java虚拟机的 ...
- Windows下64位Apache服务器的安装
转自:http://www.blogjava.net/greatyuqing/archive/2013/02/13/395308.html 首先需要说明的是,Apaceh服务器没有官方的64位版本,只 ...
- java环境变量配置(转)
java环境变量配置 windows xp下配置JDK环境变量: 1.安装JDK,安装过程中可以自定义安装目录等信息,例如我们选择安装目录为D:\java\jdk1.5.0_08: 2.安装完成后,右 ...
- HDU 4343 贪心
D - Interval queryTime Limit: 1.5 Sec Memory Limit: 256 MB Description This is a very simple questio ...
- LoadRunner中多值关联的3种处理方式
需求:通过关联取得的ParamName参数可能存在多个值,需要对每个ParamName参数值进行处理 脚本:可通过3种不同的实现方式,将每个参数值作为HTTP请求内容发出 web_reg_save_ ...
- Linux常用命令_(磁盘管理)
磁盘信息:df.du df命令–功能:检查文件系统的磁盘空间占用情况–语法:df [选项]–选项:-a 显示所有文件系统的磁盘使用情况,包括0块(block)的文件系统,如/proc文件系统.-k 以 ...
- vim 全局替换命令
语法 :[addr]s/源字符串/目的字符串/[option] :%s/源字符串/目的字符串/c 全局替换命令为: :%s/源字符串/目的字符串/g [add ...
- Laravel环境配置之安装Homestead
laravel requirements: PHP >= 5.5.9 (机器上yum安装的是5.3.3) OpenSSL PHP Extension PDO PHP Extension Mb ...
- logback 配置详解【讲解较全的博客网站】
http://blog.csdn.net/haidage/article/category/812478 详解(一)http://blog.csdn.net/haidage/article/detai ...