线段树之扫描线思路

运用线段树+扫描线方式
可以解决经典的求矩形面积交问题


以HDU_1542 Atlantis 题为例

线段树和扫描线是这么结合的


    线段树统计的是有效区间段的长度 也就是扫描线 当前扫描到的区间段是哪一个
    什么意思 比如当前在哪一个段扫描 那么线段树中的t[1]中的len就是多长
    线段树一般情况下是一个后序遍历先把孩子节点的信息 更新后 再拿孩子节点的信息回来更新自己

    一旦取消这个线段 遇到了出边 那么就把这个点的覆盖情况置空 然后让这个点的信息为左右两个孩子的信息 统计
    如果这个时候左右两个孩子还有边的信息 那么依然会反馈回来 如果没有 那么这个线段就会置零


    总的来说 线段树统计的就是当前扫描时段真正的有效长度是多少
    如何通过线段树去统计?
    以离散化横坐标为例
    线段树每个叶子节点统计的都是我们所有出现过的从小到大的离散化后的x坐标顺序下标
    比如一共出现了10 15 20 25四个x坐标 由于我们离散化的是横坐标 也就是要拿横坐标建树
    也就是这四个点分别对应0 1 2 3 四个点
    把线段树建成了
    那么每次我们扫描到一个线段 就到线段树中去更新这个线段
    什么意思? 就是按照这个线段是出边还是入边
    如果是矩形入边 那么就把这个线段拿到线段树中去 我们不是已经把线段树按照对应x左边建好了吗
    那么现在遇到一个入边 按照我们之前说的线段树需要维护的东西————“当前扫描的线段所在的矩形的有效宽度”
    我们需要让线段树明白现在的有效宽度是不是变化了
    也就是把这个变得起始坐标 结束坐标搞下来 更新到线段树中
    这样我们到时候一查线段树的有效宽度 然后再用高度做一下差
    就知道当前扫描矩形的有效面积是多少了
    那么我们拿到当前边的两个坐标 去线段树中更新
    如果这个区间段在线段树中没有标记过 那么就去标记
    标记后反馈给父节点
    不断的反馈 最后父节点得到了当前状态下的有效宽度

    那么如果当前边是个出边 也就是有可能需要减少

    依然是拿到线段树中 把宽度取消

    当我们遍历了扫描方向上的所有的边 也就是把每一块的面积都累加了起来 

也就是实现了面积统计 复杂度O(edge*logn)
HDU_1542 Atlantis CODE:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 110;
struct node{int xx;double len;int l,r;
}t[maxn<<3];
double x[maxn<<2];
int xtot;
struct edge{double l,r,h;int xx;edge(){}edge(double a,double b,double c,int cover):l(a),r(b),h(c),xx(cover){}bool operator<(const edge &E){return h<E.h;}
}e[maxn<<2];
int etot;
bool cmp(int a,int b){return a<b;
}
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
void build(int l,int r,int rt){t[rt].l = l;t[rt].r = r;t[rt].xx = t[rt].len = 0;if(l==r)return;int mid = l+r>>1;build(lson);build(rson);
}
void pushup(int now){if(t[now].xx){t[now].len = x[t[now].r+1]-x[t[now].l];}else if(t[now].l==t[now].r){t[now].len=0;}else {t[now].len = t[now<<1].len+t[now<<1|1].len;}
}void update(int l,int r,int rt,int val){if(t[rt].l==l&&t[rt].r==r){t[rt].xx += val;pushup(rt);return;}int mid = t[rt].l+t[rt].r>>1;//*****if(r<=mid)update(l,r,rt<<1,val);else if(l>mid)update(l,r,rt<<1|1,val);else{update(l,mid,rt<<1,val);update(mid+1,r,rt<<1|1,val);}pushup(rt);
}
int main()
{int n,test=0;while(scanf("%d",&n),n){double x1,x2,y1,y2;test++;for(int i=1;i<=n;i++){scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);e[etot++] = edge(x1,x2,y1,1);e[etot++] = edge(x1,x2,y2,-1);x[xtot++] = x1;x[xtot++] = x2;}sort(e,e+etot);sort(x,x+xtot);xtot = unique(x,x+xtot)-x;//离散化x坐标double ans =0;build(0,xtot-1,1);for(int i=0;i<etot;i++){int l = lower_bound(x,x+xtot,e[i].l)-x;int r = lower_bound(x,x+xtot,e[i].r)-x-1;//区间这里并不是完全包含比如10,15,20,25 的区间 查询10-15 那么去查的就是10-10//什么意思 因为线段树仍然是离散的统计结构 仍然还是按照起点查询区间线段update(l,r,1,e[i].xx);ans+=(e[i+1].h-e[i].h)*t[1].len;}printf("Test case #%d\nTotal explored area: %.2f\n\n",test,ans);etot = 0;xtot = 0;}return 0;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/425227.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

74 param动作

定义一个logind的jsp <% page language"java" import"java.util.*" contentType"text/html; charsetutf-8"%><!DOCTYPE html> <html> <head> <meta charset"ISO-8859-1"> <title>Insert title h…

Unknown column 'user_uid' in 'field list' sql错误解决过程

在idea中运行一直有错&#xff0c;找了好多个地方都找不到&#xff0c;以为是我的字段名字写错了&#xff0c;然而都是对的。 把错误的这个字段删了再打一遍就好了&#xff0c; 转载于:https://www.cnblogs.com/zxrxzw/p/10630164.html

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第9篇]香农对熵和信息的定义是什么?

这是计算机理论的最后一篇.我们讨论信息理论的基础概念,什么是香农定义的熵和信息. 熵 熵与确定性成反比 信息 密码学实例 [1] Thomas M. Cover and Joy A. Thomas. Elements of Information Theory ​ 2nd Edition. Wiley-Interscience, 2 edition, July 2006. [2] S. Vaj…

数据结构:(5)算法分析基础

算法时间复杂度分析 算法空间复杂度分析

[Leetcode][第35题][JAVA][搜索插入位置][二分法]

【问题描述】[中等] 【解答思路】 二分法 时间复杂度&#xff1a;O(LogN) 空间复杂度&#xff1a;O(1) public class Solution {public int searchInsert(int[] nums, int target) {int len nums.length;if (len 0) {return 0;}// 特判if (nums[len - 1] < target) {re…

数据结构:(6)其他情况的算法分析

最好&#xff0c;最坏,平均复杂度分析 递归算法的时间复杂度分析

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第10篇]RSA和强RSA问题有什么区别

这个密码学52件事数学知识的第一篇,也是整个系列的第10篇.这篇介绍了RSA问题和Strong-RSA问题,指出了这两种问题的不同之处. 密码学严重依赖于这样的假设,某些数学问题难以在有限的时间内解决.让我们看公钥(非对称)密码学,这也是这篇文章中我们使用的一个假设----**单向函数(O…

第十三期:你所了解的javascript?

在介绍JavaScript之前&#xff0c;首先让我们来简单了解一下脚本语言。大家知道&#xff0c;HTML通常用于格式化和链接文本&#xff0c;各种编程语言通常用于向机器发出一系列复杂的指令&#xff0c;而脚本语言是介于HTML和C、Java等编程语言之间的语言。脚本语言是一种简单的语…

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第12篇]椭圆曲线上的群理论是什么

这是系列中的第12篇,我们继续数学背景的部分,通过介绍椭圆曲线的群理论… 椭圆曲线群定律是一种在一组椭圆曲线有理点中定义的二元操作来形成一个群的方法.现在,让我们看看到底什么意思,和这个东西怎么用 椭圆曲线和它的有理点 在椭圆曲线中加入群理论 这就是全部了吗 这和密…

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第13篇]概述投影点表达的用途的优点

这是52密码学系列中第13篇,我们继续数学背景部分,通过概述投影点表达的使用和优点. TLDR - 在椭圆曲线点上的翻倍和加法操作需要一个域取逆和几个乘法操作.我们考虑域K(特征值既不是2也不是3).给定K上的一个逆运算是比乘法更花费时间的,因此用投影点坐标去计算这些操作是更有效…

第七期:Python 从入门到精通:一个月就够了!

Python 从入门到精通&#xff1a;一个月就够了&#xff01; 对于许多未曾涉足计算机编程的领域「小白」来说&#xff0c;深入地掌握 Python 看似是一件十分困难的事。其实&#xff0c;只要掌握了科学的学习方法并制定了合理的学习计划&#xff0c;Python 从 入门到精通只需要一…

[Leetcode][第97题][JAVA][交错字符串][BFS][动态规划]

【问题描述】[中等] 【解答思路】 1. 动态规划 第 1 步&#xff1a;设计状态 f(i,j) 表示 s 1的前 i个元素和 s2 的前 j个元素是否能交错组成 s3的前 i j 个元素 第 2 步&#xff1a;状态转移方程 p i j - 1 p为s3的长度 第 3 步&#xff1a;考虑初始化 boolean[][] f …

关于Windows下的访问控制模型

在探索Windows操作系统的过程中&#xff0c;发现很多有意思 的东西。 Windows下的访问控制模型也是我在Github上浏览代码时&#xff0c;无意中发现的。 项目地址 https://github.com/Krutonium/Windows-10-Login-Background-Changer 当我们登陆Windows操作系统时&#xff0c;系…

第八期:继美商务部拉黑多家中国公司后,MIT开始审查对华AI合作项目

10 月 9 日&#xff0c;美国麻省理工学院&#xff08;MIT&#xff09;表示&#xff0c;将审查学校与商汤科技&#xff08;SenseTime Group Ltd.&#xff09;的关系&#xff0c;包括一些可能涉及出口管制法规的项目。 北京时间 10 月 8 日&#xff0c;美国商务部正式公布了新一批…

[Leetcode][第174题][JAVA][地下城游戏][DFS][动态规划]

【问题描述】[中等] 【解答思路】 1. 回溯&#xff08;暴力&#xff09;& 优化 超时&#xff0c;需要优化 public int calculateMinimumHP(int[][] dungeon) {if (dungeon null || dungeon.length 0 || dungeon[0].length 0) {return 0;}int rowLen dungeon.length;in…

第十期:快来了解这五种热门的开发技能

开发人员是热门的工作岗位之一&#xff0c;在Indeed网站的2019年最热门工作排行榜上名次靠前。随着企业对数字化转型项目的需求不断增加&#xff0c;对能够开发这些数字化应用软件的个人的需求随之而来。 开发人员是热门的工作岗位之一&#xff0c;在Indeed网站的2019年最热门工…

[剑指offer]面试题第[49]题[Leetcode][第264题][JAVA][丑数][动态规划][堆]

【问题描述】[中等] 【解答思路】 1. 动态规划 时间复杂度&#xff1a;O(N) 空间复杂度&#xff1a;O(N) class Solution {public int nthUglyNumber(int n) {int a 0, b 0, c 0;int[] dp new int[n];dp[0] 1;for(int i 1; i < n; i) {int n2 dp[a] * 2, n3 dp[…

第十二期:常用的几种大数据架构剖析

常用的几种大数据架构剖析 随着大数据技术的发展&#xff0c;数据挖掘、数据探索等专有名词曝光度越来越高&#xff0c;但是在类似于Hadoop系列的大数据分析系统大行其道之前&#xff0c;数据分析工作已经经历了长足的发展&#xff0c;尤其是以BI系统为主的数据分析&#xff0…

【大数据】获取一篇新闻的全部信息

作业要求来自于&#xff1a;https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/2894 给定一篇新闻的链接newsUrl&#xff0c;获取该新闻的全部信息 标题、作者、发布单位、审核、来源 发布时间:转换成datetime类型 点击&#xff1a; newsUrlnewsId(使用正则表达式re)cl…