Atlantis HDU - 1542 线段树+扫描线 求交叉图形面积
//永远只考虑根节点的信息,说明在query时不会调用pushdown
//所有操作均是成对出现,且先加后减
//
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int N = ;
int n;
//存每一个操作
struct Segment
{
//区间长度
double x;
//纵坐标
double y1, y2;
//权值
int k;
//按横坐标排序
bool operator< (const Segment &t)const
{
return x < t.x;
}
}seg[N * ];
struct Node
{
int l, r;
//被覆盖的次数是多少
int cnt;
//所有权值大于0的长度和是多少
//不考虑祖先节点cnt的前提下(永远只向下看),cnt>0的区间总长
double len;
}tr[N * ];
//离散化,y
vector<double> ys;
//找离散化之后的值
int find(double y)
{
return lower_bound(ys.begin(), ys.end(), y) - ys.begin();
} void pushup(int u)
{
if (tr[u].cnt)
// r+1才是下标 ,减完之后是长度
tr[u].len = ys[tr[u].r + ] - ys[tr[u].l];
//如果不是叶节点,再用两个儿子算
else if (tr[u].l != tr[u].r)
{
tr[u].len = tr[u << ].len + tr[u << | ].len;
}
//如果是叶节点
else tr[u].len = ;
} void build(int u, int l, int r)
{
// cnt是0,len是0
tr[u] = {l, r, , };
if (l != r)
{
int mid = l + r >> ;
build(u << , l, mid), build(u << | , mid + , r);
}
} void modify(int u, int l, int r, int k)
{
//
if (tr[u].l >= l && tr[u].r <= r)
{
tr[u].cnt += k;
pushup(u);
}
else
{
int mid = tr[u].l + tr[u].r >> ;
if (l <= mid) modify(u << , l, r, k);
if (r > mid) modify(u << | , l, r, k);
pushup(u);
}
}
int main()
{
int T = ;
while (scanf("%d", &n), n)
{
ys.clear();
for (int i = , j = ; i < n; i ++ )
{
double x1, y1, x2, y2;
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
//对应的区间加1
seg[j ++ ] = {x1, y1, y2, };
//对应的区间减1
seg[j ++ ] = {x2, y1, y2, -};
ys.push_back(y1), ys.push_back(y2);
}
//对应区间
//离散化
sort(ys.begin(), ys.end());
ys.erase(unique(ys.begin(), ys.end()), ys.end());
//从1号点开始,存的是区间,所以是0到ys.size()-2
build(, , ys.size() - );
//排序
sort(seg, seg + n * );
double res = ;
for (int i = ; i < n * ; i ++ )
{
//第一条线不能加 ,0的时候,还没点加进去
if (i > )
// 为1的长度 区间长度
res += tr[].len * (seg[i].x - seg[i - ].x);
//要把当前的操作 加 到线段树里去
// 左区间 右区间 权值
modify(, find(seg[i].y1), find(seg[i].y2) - , seg[i].k);
}
printf("Test case #%d\n", T ++ );
printf("Total explored area: %.2lf\n\n", res);
}
return ;
}
Atlantis HDU - 1542 线段树+扫描线 求交叉图形面积的更多相关文章
- hdu 1542 线段树+扫描线 学习
学习扫描线ing... 玄学的东西... 扫描线其实就是用一条假想的线去扫描一堆矩形,借以求出他们的面积或周长(这一篇是面积,下一篇是周长) 扫描线求面积的主要思想就是对一个二维的矩形的某一维上建立一 ...
- HDU 1542 线段树+扫描线+离散化
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- hdu 1542 线段树扫描(面积)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- hdu 4052 线段树扫描线、奇特处理
Adding New Machine Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- hdu 1828 线段树扫描线(周长)
Picture Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- HDU 1828“Picture”(线段树+扫描线求矩形周长并)
传送门 •参考资料 [1]:算法总结:[线段树+扫描线]&矩形覆盖求面积/周长问题(HDU 1542/HDU 1828) •题意 给你 n 个矩形,求矩形并的周长: •题解1(两次扫描线) 周 ...
- hdu1542 Atlantis 线段树--扫描线求面积并
There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some ...
- hdu1542 线段树扫描线求矩形面积的并
题意: 给你n个正方形,求出他们的所占面积有多大,重叠的部分只能算一次. 思路: 自己的第一道线段树扫描线题目,至于扫描线,最近会写一个总结,现在就不直接在这里写了,说下我的方 ...
- hdu 5091(线段树+扫描线)
上海邀请赛的一道题目,看比赛时很多队伍水过去了,当时还想了好久却没有发现这题有什么水题的性质,原来是道成题. 最近学习了下线段树扫描线才发现确实是挺水的一道题. hdu5091 #include &l ...
随机推荐
- HDU_3410_单调栈
http://acm.hdu.edu.cn/showproblem.php?pid=3410 初探单调栈,从左往右,求l,从右往左,求r. #include<iostream> #incl ...
- CCF_201503-1_图像旋转
水. #include<iostream> #include<cstdio> using namespace std; ][]; int main() { int n,m; c ...
- Codeforces 1304E 1-Trees and Queries (树上距离+思维)(翻译向)
题意 给你一棵树,q个询问(x,y,a,b,k),每次问你如果在(x,y)加一条边,那么a到b能不能走k步,同一个点可以走多次 思路(翻译题解) 对于一条a到b的最短路径x,可以通过左右横跳的方法把他 ...
- javascript js全部的 全局属性 和 方法-window
window method: open(URL,窗口名称,窗口风格)//打开一个新的窗口,并在窗口中装载指定URL地址的网页 close()//close方法用于自动关闭浏览器窗口 alert(提示字 ...
- python3 ansible api 命令和playbook
一.api代码 # coding: utf-8 import os import sys from collections import namedtuple from ansible.parsing ...
- SpringBoot基础篇-SpringBoot快速入门
SpringBoot基础 学习目标: 能够理解Spring的优缺点 能够理解SpringBoot的特点 能够理解SpringBoot的核心功能 能够搭建SpringBoot的环境 能够完成applic ...
- 解决pycharm打开html页面一直刷新
顺序——> File ——>Project:项目名——>project Structure 右侧的 + Add ContentRoot下面只保留本项目路径,其他全删了 方法2(推荐) ...
- Nginx之常用基本配置
上一篇博客我们大概介绍了一下nginx,nginx的架构,nginx编译安装和nginx命令的用法,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/1236680 ...
- [CSGO]跑图CFG
bot_kick //剔除所有电脑 sv_cheats 1 //允许作弊指令 bot_stop 1 //bot静止 mp_warmup_end //结束热身时间 mp_freezetime 0 //开 ...
- C语言:字符串拷贝(截取)、查找
C语言:字符串拷贝(截取).查找 很惭愧,学了这么久别的语言,一直没有好好学C和C++,所以现在开始认真C/C++的一些特性和比较,这里记录下C语言拷贝和截取的一些方式,由于系统库带的函数不方便,所以 ...