O - 覆盖的面积 - hdu 1255(求面积)
分析:求一层的面积覆盖是非常简单的事情,不过多层面积覆盖应该怎么搞???也是比较简单的事情,只需要用两个变量记录就好了,一个记录覆盖一次的,一个记录覆盖两次的,就很容易解决了
#include<stdio.h>
#include<algorithm>
#include<math.h>
using namespace std; #define Lson r<<1
#define Rson r<<1|1 const int MAXN = 1e5+; struct segmentTree
{///cover 记录区间被覆盖了多少次
int L, R, cover;
double len1, len2;///分别记录被覆盖一次和多次时候的长度
int mid(){return (L+R)>>;}
}a[MAXN<<];
///保存离散化后的数据,nh是数组大小
double Hash[MAXN]; int nh; ///dir等于 1 是y的左边, -1是y的右边
struct Point{double x, y1, y2; int dir;}ege[MAXN];
bool cmp(Point n1, Point n2)
{///按照x从小到大排序
return n1.x < n2.x;
}
double FindSegLen(int y1, int y2)
{///查找线段的长度, y1 < y2
return Hash[y2] - Hash[y1];
}
void BuildTree(int r, int L, int R)
{
a[r].L = L, a[r].R = R, a[r].cover = ;
a[r].len1 = a[r].len2 = ; if(L == R-)return ; BuildTree(Lson, L, a[r].mid());
BuildTree(Rson, a[r].mid(), R);
}
void PushUp(int r)
{
if(a[r].cover > )
a[r].len1 = a[r].len2 = FindSegLen(a[r].L, a[r].R);
else if(a[r].L == a[r].R- && a[r].cover == )
a[r].len1 = FindSegLen(a[r].L, a[r].R), a[r].len2 = ;
else if(a[r].L == a[r].R-)
a[r].len1 = a[r].len2 = ;
else if(a[r].cover == )
{///不是叶子节点点,覆盖两次以上的就等于子树覆盖一次的
a[r].len2 = a[Lson].len1 + a[Rson].len1;
a[r].len1 = FindSegLen(a[r].L, a[r].R);
}
else
{///区间未被覆盖过,只能等于子树被覆盖的情况
a[r].len1 = a[Lson].len1 + a[Rson].len1;
a[r].len2 = a[Lson].len2 + a[Rson].len2;
}
}
void UpData(int r, int L, int R, int dir)
{///注意叶子节点的合并操作
if(a[r].L == L && a[r].R == R)
{
a[r].cover += dir;
PushUp(r); return ;
} if(R <= a[r].mid())
UpData(Lson, L, R, dir);
else if(L >= a[r].mid())
UpData(Rson, L, R, dir);
else
{
UpData(Lson, L, a[r].mid(), dir);
UpData(Rson, a[r].mid(), R, dir);
} PushUp(r);
} int main()
{
int i, T, N; scanf("%d", &T); while(T--)
{
double x1, x2, y1, y2, area=; int k=; nh = ; scanf("%d", &N); for(i=; i<N; i++)
{
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
ege[k].x=x1, ege[k].y1=y1, ege[k].y2=y2, ege[k++].dir=;///左边
ege[k].x=x2, ege[k].y1=y1, ege[k].y2=y2, ege[k++].dir=-;///右边
Hash[nh++] = y1, Hash[nh++] = y2;
} sort(Hash, Hash+nh);///排序并且去重复
nh = unique(Hash, Hash+nh) - Hash; ///建立以1区间为单位的线段树
BuildTree(, , nh-); ///对y边按照x从小到大排序
sort(ege, ege+k, cmp); for(int i=; i<k-; i++)
{
int L = lower_bound(Hash, Hash+nh, ege[i].y1)-Hash;
int R = lower_bound(Hash, Hash+nh, ege[i].y2)-Hash; UpData(, L, R, ege[i].dir);; area += a[].len2 * (ege[i+].x - ege[i].x);
} printf("%.2f\n", area);
} return ;
}
O - 覆盖的面积 - hdu 1255(求面积)的更多相关文章
- 线段树扫描线(一、Atlantis HDU - 1542(覆盖面积) 二、覆盖的面积 HDU - 1255(重叠两次的面积))
扫描线求周长: hdu1828 Picture(线段树+扫描线+矩形周长) 参考链接:https://blog.csdn.net/konghhhhh/java/article/details/7823 ...
- 覆盖的面积 HDU - 1255(扫描线求面积交)
题意: 就是扫描线求面积交 解析: 参考求面积并.... 就是把down的判断条件改了一下..由w > 0 改为 w > 1 同时要讨论一下 == 1 时 的情况, 所以就要用到一个临时 ...
- 覆盖的面积 HDU - 1255 (扫描线, 面积交)
求n个矩阵面积相交的部分,和求面积并一样,不过这里需要开两个数组保存覆盖一次和覆盖两次以上的次数的部分,还是模板,主要注意点就是pushup部分,如果我已经被两次覆盖,那我的两个数组在这个root点的 ...
- 面积并+扫描线 覆盖的面积 HDU - 1255
题目链接:https://cn.vjudge.net/problem/HDU-1255 题目大意:中文题目 具体思路:和上一篇的博客思路差不多,上一个题求的是面积,然后我们这个地方求的是啊覆盖两次及两 ...
- 覆盖的面积 HDU - 1255 线段树+扫描线+离散化 求特定交叉面积
#include<cstdio> #include<map> #include<algorithm> using namespace std; ; struct N ...
- 覆盖的面积(HDU 1255 线段树)
覆盖的面积 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Problem D ...
- 覆盖的面积 HDU - 1255 (线段树-扫描线)模板提
给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1& ...
- 扫描线三巨头 hdu1928&&hdu 1255 && hdu 1542 [POJ 1151]
学习链接:http://blog.csdn.net/lwt36/article/details/48908031 学习扫描线主要学习的是一种扫描的思想,后期可以求解很多问题. 扫描线求矩形周长并 hd ...
- hdu 1255 覆盖的面积(求覆盖至少两次以上的面积)
了校赛,还有什么途径可以申请加入ACM校队? 覆盖的面积 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K ...
随机推荐
- Garbage Collectors - Serial vs. Parallel vs. CMS vs. G1 (and what's new in Java 8)--转
The 4 Java Garbage Collectors - How the Wrong Choice Dramatically Impacts Performance The year is 20 ...
- 修改MySQL引擎
1. 显示MySQL支持的引擎:show engines;
- Android 面试精华题目总结
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24015867 下面的题目都是楼主在android交流群大家面试时遇到的,如果大家 ...
- 【网络流#4】UVA 753 最大流
最近开始刷网络流的题目了,先从紫书上的开始,这道题是P374上的,嘛,总之这道题最终还是参考了一下紫书. 中间是用了STL中map将字符串映射成编号,使用编号总比是用字符串简单的多. 超级源点S与各个 ...
- hdu 2189
//hdu2189 题意大概就是给n个人,分成多组,要求每组人数都是素数,求有多少种... 解法就是先把150以内的素数全部存入一个数组,然后利用a[j+b[i]]+=a[j];这道题一开始没理解 ...
- 手机端input,select屏蔽浏览器默认事件
文本框input:当文本框focus时会弹出软键盘,有时我们需要click事件而又不想触发focus事件(不要弹出软键盘) 给input添加 disabled="disabled" ...
- 2015-09-28 Javascript
1.Javascript是什么? JavaScript是一种脚本语言,结构简单,使用方便,其代码可以直接放入HTML文档中,可以直接在支持JavaScript的浏览器中运行.JavaSript. Ja ...
- linux 分区
1.硬盘分区分为基本分区和扩展分区, 扩展分区分下去就是逻辑分区,而且逻辑分区没有数量上的限制. 2.查看linux系统分区具体情况 fdisk - l 3.查看某个目录是哪个分区下的 df /boo ...
- iOS中使用图片作为颜色的背景图
Objective-C: [UIColor colorWithPatternImage:[UIImage imageNamed:@"jpg"]]; Swift: UIColor(p ...
- 单点登录CAS使用记(二):部署CAS服务器以及客户端
CAS-Server下载地址:https://www.apereo.org/projects/cas/download-cas CAS-Client下载地址:http://developer.jasi ...