poj1511,线段树扫描线面积
经典题,线段树扫描线其实类似区间更新,一般的做法是想象一根扫描线从上扫到下或者从左扫到右,本题的做法是从上扫到下
只要扫到了一根水平线,就将其更新到线段树对应区间中,区间和它的子区间是独立更新的
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define maxn 2000
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
struct Seg{
double l,r,h;
int d;
Seg(){}
Seg(double a,double b,double c,int dd):l(a),r(b),h(c),d(dd){}
bool operator<(const Seg & a)const{
return h<a.h;
}//从下往上扫描
}segs[maxn];//横线段
double data[maxn];
int tot,m;//data统计高度
int cnt[maxn<<];//覆盖了这一整个区间的入边数 - 覆盖了这一整个区间的出边数
double sum[maxn<<];//区间当前被覆盖的长度
inline void pushup(int l,int r,int rt){
//前两个if对应的是update中(L<=l && R>=r)的pushup,后一个if对应的是分开更新后的update
if(cnt[rt])//如果这个区间都被覆盖了
sum[rt]=data[r+]-data[l];
else if (l==r)//如果是单位段并且cnt[rt]==0,说明这一段就是没有被覆盖
sum[rt]=;
else sum[rt]=sum[rt<<]+sum[rt<<|];
}
//更新函数update:如果整个区间被更新,分三种情况:1.这个区间被完全覆盖 2.这个区间是空白单位区间(没有子区间) 3.这个区间没有被完全覆盖
void update(int L,int R,int c,int l,int r,int rt){
if(L<=l && R>=r){
cnt[rt]+=c;
pushup(l,r,rt);//为什么这里也会有pushup?因为pushup的功能不只是合并两个区间而已,它还能计算这个区间的覆盖长度
return;
}
int m=l+r>>;
if(L<=m) update(L,R,c,lson);
if(R>m) update(L,R,c,rson);
pushup(l,r,rt);
}
void init(){
tot=m=;
memset(cnt,,sizeof cnt);
memset(sum,,sizeof sum);
}
int main(){
int T=,n;
while(scanf("%d",&n) && n){
init(); for(int i=;i<=n;i++){
double x1,y1,x2,y2;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
segs[tot]=Seg(x1,x2,y1,);data[tot++]=x1;
segs[tot]=Seg(x1,x2,y2,-);data[tot++]=x2;
}
sort(segs,segs+tot);
sort(data,data+tot);
m=unique(data,data+tot)-data; double ret=;
for(int i=;i<tot;i++){
int posl=lower_bound(data,data+m,segs[i].l)-data;
int posr=lower_bound(data,data+m,segs[i].r)-data-;
if(posl<=posr)
update(posl,posr,segs[i].d,,m,);//把这条边更新到线段树中
ret+=sum[]*(segs[i+].h-segs[i].h);
}
printf("Test case #%d\nTotal explored area: %.2lf\n\n",++T , ret);
}
return ;
}
poj1511,线段树扫描线面积的更多相关文章
- HDU 1255 覆盖的面积 (线段树扫描线+面积交)
自己YY了一个的写法,不过时间复杂度太高了,网上的想法太6了 题意:给你一些矩阵,求出矩阵的面积并 首先按照x轴离散化线段到线段树上(因为是找连续区间,所以段建树更加好做). 然后我们可以想一下怎样 ...
- HDU 3265 Posters (线段树+扫描线)(面积并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3265 给你n个中间被挖空了一个矩形的中空矩形,让你求他们的面积并. 其实一个中空矩形可以分成4个小的矩 ...
- [USACO18JAN] Lifeguards S (线段树:扫描线面积)
扫描线裸题没什么好说的 注意空间不要开小了!!! #include <cstdio> #include <cstring> #include <algorithm> ...
- hdu 3265 Posters(线段树+扫描线+面积并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3265 题意:给你一张挖了洞的墙纸贴在墙上,问你总面积有多少. 挖了洞后其实就是多了几个矩形墙纸,一张墙 ...
- POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]
题意:求矩形面积并 分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化! 把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区 ...
- hdu1542 Atlantis 线段树--扫描线求面积并
There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some ...
- hdu1255 覆盖的面积 线段树-扫描线
矩形面积并 线段树-扫描线裸题 #include<stdio.h> #include<string.h> #include<algorithm> #include& ...
- HDU 1264 Counting Squares (线段树-扫描线-矩形面积并)
版权声明:欢迎关注我的博客.本文为博主[炒饭君]原创文章,未经博主同意不得转载 https://blog.csdn.net/a1061747415/article/details/25471349 P ...
- 覆盖的面积 HDU - 1255 (线段树-扫描线)模板提
给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1& ...
随机推荐
- JAVA分布式架构的演进
系统架构演化历程-初始阶段架构 初始阶段 的小型系统 应用程序.数据库.文件等所有的资源都在一台服务器上通俗称为LAMP 特征:应用程序.数据库.文件等所有的资源都在一台服务器上. 描述:通常服务器操 ...
- GoLang基础数据类型-切片(slice)详解
GoLang基础数据类型-切片(slice)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 数组的长度在定义之后无法再次修改:数组是值类型,每次传递都将产生一份副本.显然这种数 ...
- Random类(随机数)
前言:总是忘记怎么用.上网一查,都是些有的没的...... 最简单却最常用的方法:Random.Next方法 首先,为Random类实例化一个对象: Random n=new Random(); Ne ...
- Overload和Override的区别 C++ Java
Overload:顾名思义,就是Over(重新)——load(加载),所以中文名称是重载. 它可以表现类的多态性,可以是函数里面可以有相同的函数名但是参数名.返回值.类型不能相同: 或者说可以改变参数 ...
- socket技术详解(看清socket编程)
socket编程是网络常用的编程,我们通过在网络中创建socket关键字来实现网络间的通信,通过收集大量的资料,通过这一章节,充分的了解socket编程,文章用引用了大量大神的分析,加上自己的理解,做 ...
- 震惊!最全PyCharm教程
PyCharm PyCharm是一个用于计算机编程的集成开发环境(IDE),主要用于Python语言开发,由捷克公司JetBrains开发,提供代码分析.图形化调试器,集成测试器.集成版本控制系统(V ...
- luogu 1314 欧拉回路
欧拉路径:一笔画的路径 欧拉回路:一笔画的回路 两者判断方法一样但是输出略有不同.并且还有Fleury(弗罗莱)算法,但是我不会.. 这里就用dfs就好 判断条件: 1)图的连通性(可用并查集判断) ...
- Anaconda3 指南
Anaconda 是一个 Python 的生态.它包含很多的科学计算库和大数据处理工具等. $ python --version Python 3.6.1 :: Anaconda 4.4.0 (64- ...
- 第3月第1天 GCDAsyncSocket dispatch_source_set_event_handler runloop
+ (void)startCFStreamThreadIfNeeded { LogTrace(); static dispatch_once_t predicate; dispatch_once(&a ...
- HTTP状态码解析
HTTP状态码(HTTP Status Code)是用以表示网页服务器HTTP响应状态的3位数字代码.它由 RFC 2616 规范定义的,并得到RFC 2518.RFC 2817.RFC 2295.R ...