有点难,扫描线易懂,离散化然后线段树处理有点不太好理解。

因为这里是一个区间,所有在线段树中更新时,必须是一个长度大于1的区间才是有效的,比如[l,l]这是一根线段,而不是区间了。

AC代码

#include <stdio.h>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = + ; struct Line{
double x, y1, y2;
int flag;
Line(double a, double b, double c, int d) {
x = a; y1 = b; y2 = c; flag = d;
}
bool operator < (const Line& a) const {
return x < a.x;
}
}; vector<Line> line;
map<double, int> Hash;
vector<double> y; double p[maxn << ]; // 区间长度
int covers[maxn << ]; // 覆盖次数
double len[maxn << ]; // 覆盖长度 void buildTree(int o, int l, int r) {
len[o] = covers[o] = ;
p[o] = y[r] - y[l];
if(l + != r) {
int m = (l+r) / ;
buildTree(o*, l, m);
buildTree(o*+, m, r);
}
} int ul, ur;
void update(int o, int l, int r, int f) {
if(l+ == r) {
covers[o] += f;
if(covers[o] == ) len[o] = ;
else len[o] = p[o];
}
else {
int m = (l+r) / ;
if(ul < m) update(o*, l, m, f);
if(m < ur) update(o*+, m, r, f);
// pushUp
len[o] = len[o*] + len[o*+];
}
} int main() {
int n, kase = ;
while(scanf("%d", &n) == && n) {
Hash.clear(); line.clear(); y.clear();
double x1, y1, x2, y2;
for(int i = ; i < n; i++) {
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
line.push_back(Line(x1, y1, y2, ));
line.push_back(Line(x2, y1, y2, -));
y.push_back(y1);
y.push_back(y2);
} sort(line.begin(), line.end());
sort(y.begin(), y.end());
y.erase(unique(y.begin(), y.end()), y.end());
for(int i = ; i < (int)y.size(); i++) {
Hash[y[i]] = i;
} buildTree(, , y.size()-);
double ans = ;
for(int i = ; i < line.size(); i++) {
if(i > ) ans += (line[i].x - line[i-].x) * len[];
ul = Hash[line[i].y1]; ur = Hash[line[i].y2];
update(, , y.size()-, line[i].flag);
}
printf("Test case #%d\nTotal explored area: %.2f\n\n", kase++, ans);
}
return ;
}

如有不当之处欢迎指出!

poj1151 Atlantis (线段树+扫描线+离散化)的更多相关文章

  1. HDU 1542 Atlantis (线段树 + 扫描线 + 离散化)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  2. POJ1151 Atlantis 线段树扫描线

    扫描线终于看懂了...咕咕了快三个月$qwq$ 对于所有的横线按纵坐标排序,矩阵靠下的线权值设为$1$,靠上的线权值设为$-1$,然后执行线段树区间加减,每次的贡献就是有效宽度乘上两次计算时的纵坐标之 ...

  3. hdu1542 Atlantis (线段树+扫描线+离散化)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  4. HDU 1542 - Atlantis - [线段树+扫描线]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...

  5. POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]

    题意:求矩形面积并 分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化! 把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区 ...

  6. hdu1542 Atlantis 线段树--扫描线求面积并

    There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some ...

  7. HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  8. HDU1542 Atlantis —— 求矩形面积并 线段树 + 扫描线 + 离散化

    题目链接:https://vjudge.net/problem/HDU-1542 There are several ancient Greek texts that contain descript ...

  9. 【42.49%】【hdu 1542】Atlantis(线段树扫描线简析)

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s) ...

随机推荐

  1. centOS 7 设置DNS方法 同之前版本不同

    在CentOS 7下,手工设置 /etc/resolv.conf 里的DNS,过了一会,发现被系统重新覆盖或者清除了.和CentOS 6下的设置DNS方法不同,有几种方式: 1.使用全新的命令行工具 ...

  2. cocos creator使用anysdk接入admob广告教程

    http://lolling787.lofter.com/post/1f5b6553_12925042 cocos creator使用anysdk接入admob广告

  3. php普通传值和引用传值 (相当通俗易懂的一篇讲解)

    首先,要理解变量名存储在内存栈中,它是指向堆中具体内存的地址,通过变量名查找堆中的内存; 普通传值,传值以后,是不同的地址名称,指向不同的内存实体; 引用传值,传引用后,是不同的地址名称,但都指向同一 ...

  4. Summary: Calculate average where sum exceed double limits

    What is a good solution for calculating an average where the sum of all values exceeds a double's li ...

  5. java学习之成员内部类

    //成员内部类:直接在类中定义 /*成员内部类的通常用法: * 通常是提供给外部类使用不进行内部类的实例化 * 因此一般把他设为私有的类用private限定 * * */ /*Demo*/ class ...

  6. linux 中的 vim 设置粘贴板

    https://blog.csdn.net/zhangxiao93/article/details/53677764 亲测有效

  7. 从拥抱开源到回馈开源,灵雀云助力CNCF中国区培训业务

    6月27日,全球首屈一指的开源盛会 2018 LinuxCon + ContainerCon + CloudOpen China (LC3)在中国北京国家会议中心落下帷幕.二度落地中国的LC3大会热度 ...

  8. elasticsearch数据备份与sshfs建立共享文件

    1.背景: 最近公司为了适应业务的发展,利用elasticsearch搜索引擎搭建了两个节点.为了防止数据丢失的特殊情况,需要定时做数据备份,而由于elasticsearch为两个节点分别在不同的服务 ...

  9. 从Redis到Codis移植实践

    一.    背景 随着业务的发展,线上Redis的数据越来越多,所以必须考虑扩容的事情了.对于redis的扩容,目前可选的方案有三种:1.client自己做sharding,一般是按key的hash值 ...

  10. Linux常用命令大全(非常全!!!)(转)

    最近都在和Linux打交道,感觉还不错.我觉得Linux相比windows比较麻烦的就是很多东西都要用命令来控制,当然,这也是很多人喜欢linux的原因,比较短小但却功能强大.我将我了解到的命令列举一 ...