HDU 1255 覆盖的面积 (扫描线 线段树 离散化 矩形面积并)
题意:中文题意。
分析:纯手敲,与上一道题目很相似,但是刚开始我以为只是把cnt》=0改成cnt>=2就行了,、
但是后来发现当当前加入的线段的范围之前 还有线段的时候就不行了,因为虽然现在都不等于
2,但是之前的那个线段加上现在的已经覆盖2次了。
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define LL __int64
#define lson l, mid, 2*rt
#define rson mid+1, r, 2*rt+1
const int maxn = +;
using namespace std;
int n;
double y[maxn];
struct node
{
int l, r, c;
double cnt, lf, rf, more; //cnt还是代表覆盖的长度,增加了more代表两次及以上覆盖的长度
}tr[*maxn];
struct Line
{
double x, y1, y2;
int f;
}line[maxn];
bool cmp(Line a, Line b)
{
return a.x < b.x;
}
void build(int l, int r, int rt)
{
tr[rt].l = l; tr[rt].r = r;
tr[rt].c = ; tr[rt].cnt = ;
tr[rt].more = ;
tr[rt].rf = y[r]; tr[rt].lf = y[l];
if(l+==r) return;
int mid = (l+r)/;
build(l, mid, *rt);
build(mid, r, *rt+);
}
void calen(int rt)
{
if(tr[rt].c==)
{
if(tr[rt].l+==tr[rt].r)
{
tr[rt].cnt = ; tr[rt].more = ;
}
else
{
tr[rt].cnt = tr[*rt].cnt+tr[*rt+].cnt;
tr[rt].more = tr[*rt].more+tr[*rt+].more;
}
}
if(tr[rt].c==) //注意这一步是关键
{
tr[rt].cnt = tr[rt].rf-tr[rt].lf;
if(tr[rt].l+==tr[rt].r) //因为没有注意是否到最后,错了一遍
tr[rt].more = ;
else
tr[rt].more = tr[*rt].cnt + tr[*rt+].cnt; //为1的时候如果下面也有就加上
}
if(tr[rt].c>=)
{
tr[rt].more = tr[rt].rf-tr[rt].lf;
tr[rt].cnt = tr[rt].more;
}
}
void update(int rt, Line e)
{
if(e.y1==tr[rt].lf && e.y2==tr[rt].rf)
{
tr[rt].c += e.f;
calen(rt);
return;
}
if(e.y2<=tr[*rt].rf) update(*rt, e);
else if(e.y1>=tr[*rt+].lf) update(*rt+, e);
else
{
Line tmp;
tmp = e;
tmp.y2 = tr[*rt].rf; update(*rt, tmp);
tmp = e;
tmp.y1 = tr[*rt+].lf; update(*rt+, tmp);
}
calen(rt);
}
int main()
{
int t, i, cnt;
double x1, x2, y1, y2, ans;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
cnt = ; ans = ;
for(i = ; i <= n; i++)
{
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
line[cnt].x = x1; line[cnt].y1 = y1;
line[cnt].y2 = y2; line[cnt].f = ;
y[cnt++] = y1;
line[cnt].x = x2; line[cnt].y1 = y1;
line[cnt].y2 = y2; line[cnt].f = -;
y[cnt++] = y2;
}
sort(y+, y+cnt);
sort(line+, line+cnt, cmp);
cnt --;
build(, cnt, );
update(, line[]);
for(i = ; i <= cnt; i++)
{
ans += tr[].more*(line[i].x - line[i-].x);
update(, line[i]);
}
printf("%.2lf\n", ans);
}
return ;
}
HDU 1255 覆盖的面积 (扫描线 线段树 离散化 矩形面积并)的更多相关文章
- HDU - 1255 覆盖的面积(线段树求矩形面积交 扫描线+离散化)
链接:线段树求矩形面积并 扫描线+离散化 1.给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. 2.看完线段树求矩形面积并 的方法后,再看这题,求的是矩形面积交,类同. 求面积时,用被覆 ...
- POJ 1151Atlantis 扫描线+线段树求矩形面积并
题目链接 #include <iostream> #include <vector> #include <cstdio> #include <cstring& ...
- hdu 5091 给定矩形覆盖尽量多点 扫描线+线段树
http://acm.hdu.edu.cn/showproblem.php?pid=5091 给你10000以内的敌舰的坐标(即分别为x,y),要求用W*H的矩形去围住一个区域,使得这个区域内的敌舰最 ...
- POJ 1151 / HDU 1542 Atlantis 线段树求矩形面积并
题意:给出矩形两对角点坐标,求矩形面积并. 解法:线段树+离散化. 每加入一个矩形,将两个y值加入yy数组以待离散化,将左边界cover值置为1,右边界置为2,离散后建立的线段树其实是以y值建的树,线 ...
- 【hdu1542】线段树求矩形面积并
分割线内容转载自http://hzwer.com/879.html ------------------------------------------------------------------ ...
- POJ 1151 Atlantis 线段树求矩形面积并 方法详解
第一次做线段树扫描法的题,网搜各种讲解,发现大多数都讲得太过简洁,不是太容易理解.所以自己打算写一个详细的.看完必会o(∩_∩)o 顾名思义,扫描法就是用一根想象中的线扫过所有矩形,在写代码的过程中, ...
- HDU 1542:Atlantis(扫描线+线段树 矩形面积并)***
题目链接 题意 给出n个矩形,求面积并. 思路 使用扫描线,我这里离散化y轴,按照x坐标从左往右扫过去.离散化后的y轴可以用线段树维护整个y上面的线段总长度,当碰到扫描线的时候,就可以统计面积.这里要 ...
- POJ1151Atlantis 矩形面积并[线段树 离散化 扫描线]
Atlantis Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 21734 Accepted: 8179 Descrip ...
- POJ 1151Atlantis 矩形面积并[线段树 离散化 扫描线]
Atlantis Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 21734 Accepted: 8179 Descrip ...
随机推荐
- SVN学习
一.SVN在线安装(Eclipse) 步骤1: 步骤2 其中http://subclipse.tigris.org/update_1.10.x是最新版本的SVN插件的下载站点[subclipse是Ec ...
- iOS10 关于推送-b
最近在研究iOS10关于推送的新特性, 相比之前确实做了很大的改变,总结起来主要是以下几点: 推送内容更加丰富,由之前的alert 到现在的title, subtitle, body 推送统一由tri ...
- .net 科学类型相关问题
Q:如果我要把使用科学记数法表示的string转换为int又该如何呢? A:你可以通过把NumberStyles.AllowDecimalPoint | NumberStyles.AllowExpon ...
- 复习linq
复习linq linq的英文是language integrated query.其中query的意思就是疑问或者计算机用语就是从资料库中提取信息的要求,可以理解为查询的意思.那么它翻译过来的话就是集 ...
- [原创] zabbix学习之旅七:如何远程操作被监控机器
虽然我们已经创建了一个报警系统,但在实际场景中,运维人员从得到报警到实际解决问题有一定的时差,若业务系统没有做高可用,那业务不得不中断,对于某些要求严格的企业级环境,这是不可容忍的,那有没有方法能让z ...
- cg 到hlsl的转换
http://msdn.microsoft.com/en-us/library/windows/desktop/ff471376(v=vs.85).aspx http://gamedev.stacke ...
- Oracle中的 UPDATE FROM 解决方法
转:http://www.cnblogs.com/JasonLiao/archive/2009/12/23/1630895.html Oracle中的 UPDATE FROM 解决方法 在表的更新操作 ...
- uva 10651
DP 主要是位运算的运用 因为只有12位 用一个数字代表一种装态 记忆化搜索 节约时间 /***************************************************** ...
- [topcoder]LongLongTripDiv2
http://community.topcoder.com/stat?c=problem_statement&pm=13091 解方程,对中国孩子太简单了. #include <vect ...
- iOS开发--计时器-NSTimer与CADisplayLink
如果程序要让某个方法重复执行,可以借助定时器来完成.CADisplayLink是一个能让我们以和屏幕刷新率相同的频率将内容画到屏幕上的定时器,NSTimer的精确度低了点,比如NSTimer的触发时间 ...