Luogu5490 【模板】扫描线(矩形的面积并)
原题链接:https://www.luogu.com.cn/problem/P5490
【模板】扫描线
题目描述
求 nnn 个矩形的面积并。
输入格式
第一行一个正整数 nnn。
接下来 nnn 行每行四个非负整数 x1,y1,x2,y2x_1, y_1, x_2, y_2x1,y1,x2,y2 ,表示一个矩形的左下角坐标为 (x1,y1)(x_1, y_1)(x1,y1),右上角坐标为 (x2,y2)(x_2, y_2)(x2,y2)。
输出格式
一行一个正整数,表示 nnn 个矩形的并集覆盖的总面积。
输入输出样例
输入 #1
2
100 100 200 200
150 150 250 255
输出 #1
18000
说明/提示
对于 20%20\%20% 的数据,1≤n≤10001 \le n \le 10001≤n≤1000。
对于 100%100\%100% 的数据,1≤n≤106,0≤x1<x2≤109,0≤y1<y2≤1091 \le n \le 10^6, 0 \le x_1 < x_2 \le 10^9, 0 \le y_1 < y_2 \le 10^91≤n≤106,0≤x1<x2≤109,0≤y1<y2≤109 。
题解
扫描线的模板题,然而原网页上的数据范围写的n≤105n\le 10^5n≤105,实际数据范围10610^6106就™离谱。
扫描线可以说是一种线段树的运用,也可以说是一种思想:在处理二维的问题时,可以先解决其中一维的问题,再沿着另一维拓展延伸。
对于求矩形面积并的问题,从多维视角上看,矩形面积实际上是一维的线段沿着另一维移动扫过的面积。这个问题转换到一维就是求出每个时刻原图形的截线长度,下图黄线所示就是若干时刻的截线:
更进一步,我们可以发现截线的长度仅在经过长方形的边时发生改变,所以有用的截线实际上只有这几条:
而截线长度的变化就是因为添加/删去了矩形的边,所以我们把矩形拆成上边和下边,从下往上遍历每个边,遇到下边时对覆盖的区间加一,遇到上边则对覆盖的区间减一;每完成一次更新,就乘以相邻边的高度差,如此就能得到矩形并的面积。
要完成区间加和整体求和的操作,只需要在离散化横坐标的基础上建立线段树维护区间被覆盖次数covcovcov和本区间内被覆盖的总长度lenlenlen。
代码
由于横坐标划分的区间是在实数域上的,所以在边界处理上与区间为整数域的线段树有所不同:
#include<bits/stdc++.h>
#define ls v<<1
#define rs v<<1|1
using namespace std;
const int M=1e6+5;
struct Edge{int le,ri,h,val;
}edge[M<<1];
bool cmp(Edge a,Edge b){return a.h<b.h;}
struct node{int le,ri,len,cov;
}tree[M<<2];
int n,tot,x[M],cot;
long long ans;
void up(int v){tree[v].len=tree[v].cov?tree[v].ri-tree[v].le:tree[ls].len+tree[rs].len;}
void build(int v,int le,int ri)
{tree[v].le=x[le],tree[v].ri=x[ri+1];if(le==ri)return;int mid=le+ri>>1;build(ls,le,mid),build(rs,mid+1,ri);
}
void cover(int v,int le,int ri,int val)
{if(le<=tree[v].le&&tree[v].ri<=ri){tree[v].cov+=val;up(v);return;}if(le<tree[ls].ri)cover(ls,le,ri,val);if(tree[rs].le<ri)cover(rs,le,ri,val);up(v);
}
void in()
{scanf("%d",&n);for(int i=1,a,b,c,d;i<=n;++i)scanf("%d%d%d%d",&a,&b,&c,&d),edge[++cot]=(Edge){a,c,b,1},edge[++cot]=(Edge){a,c,d,-1},x[++tot]=a,x[++tot]=c;
}
void ac()
{sort(x+1,x+1+tot);tot=unique(x+1,x+1+tot)-x-1;build(1,1,tot-1);sort(edge+1,edge+1+cot,cmp);for(int i=1;i<=cot;++i){ans+=1ll*tree[1].len*(edge[i].h-edge[i-1].h);cover(1,edge[i].le,edge[i].ri,edge[i].val);}printf("%lld\n",ans);
}
int main()
{in(),ac();//system("pause");
}
Luogu5490 【模板】扫描线(矩形的面积并)相关推荐
- HDU 1264 Counting Squares (线段树-扫描线-矩形面积并)
版权声明:欢迎关注我的博客.本文为博主[炒饭君]原创文章,未经博主同意不得转载 https://blog.csdn.net/a1061747415/article/details/25471349 P ...
- 蓝桥杯 油漆面积【第八届】【省赛】【A组】线段树扫面线/求矩形相交面积/模拟
资源限制 内存限制:256.0MB C/C++时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s X星球的一批考古机器人正在一片废墟上考古. 该区域的地面坚硬如 ...
- Python使用matplotlib可视化Treemap图、treemap将分层数据显示为一组嵌套矩形,每一组都用一个矩形表示,该矩形的面积与其值成正比(Treemap)
Python使用matplotlib可视化Treemap图.treemap将分层数据显示为一组嵌套矩形,每一组都用一个矩形表示,该矩形的面积与其值成正比(Treemap) 目录
- python中使用squarify包可视化treemap图:treemap将分层数据显示为一组嵌套矩形,每一组都用一个矩形表示,该矩形的面积与其值成正比
python中使用squarify包可视化treemap图:treemap将分层数据显示为一组嵌套矩形,每一组都用一个矩形表示,该矩形的面积与其值成正比 目录
- python中使用squarify包可视化treemap图:treemap将分层数据显示为一组嵌套矩形,每一组都用一个矩形表示,该矩形的面积与其值成正比、自定义设置每一个数据格的颜色
python中使用squarify包可视化treemap图:treemap将分层数据显示为一组嵌套矩形,每一组都用一个矩形表示,该矩形的面积与其值成正比.自定义设置每一个数据格的颜色 目录
- 使用类计算矩形的面积
定义并实现一个矩形类,有长和宽两个属性,由成员函数计算矩形的面积. 矩形类Rectang接口定义如下: class Rectangle { public:void setLength(int l);/ ...
- 每天一道LeetCode-----计算直方图中最大矩形的面积
Largest Rectangle in Histogram 原题链接Largest Rectangle in Histogram 给定一个直方图,计算这个直方图中最大的矩形面积.输入的是直方图中每个 ...
- python计算长方形面积代码_Python计算两个矩形重合面积代码实例
这篇文章主要介绍了Python 实现两个矩形重合面积代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 代码如下 计算两个矩形的重合面积 imp ...
- C语言 有两个矩形 求重叠面积,计算两个矩形重叠面积的简单方法
实验需要,需要计算两个矩形重叠面积 想来想去觉得挺复杂,搜了下,看见一个超给力的方法 这里分享下: function D = DecideOberlap(Reframe,GTframe) x1 = R ...
- 【C语言】输入矩形的长和宽,计算该矩形的面积
C语言学习-输入矩形的长和宽,计算该矩形的面积 原理 面积(S)= 长(length)* 宽(width) 运行效果 代码 #include<stdio.h> main() {int ...
最新文章
- CALayer-层的属性
- zigbee的路由器能分配网络地址吗_网络基础知识学习 小白也能变专家
- 读”SQL Injection Pocket Reference”之摘录
- jQuery选择器的演示
- (多线程)leetcode1116. 打印零与奇偶数
- 从业6年,给你5点建议
- How to Install and Configure OpenSSH Server In Linux
- android 9.0华为荣耀,华为9款旗舰尝鲜Android 9.0 还不快去升
- 带有审图号的区位图制作
- Linux内核态下的文件操作
- nginx简介(轻量级开源高并发web服务器:大陆使用者百度、京东、新浪、网易、腾讯、淘宝等)(并发量5w)(一般网站apache够用了,而且稳定)...
- Android.mk调用bin/shell
- 总容易混淆的排序算法:直接选择、冒泡(鸡尾酒)、直接插入(二分插入)(希尔)...
- 各种LINUX资源链接
- 城市数据大脑:小汽车儿堵成翔?NONONO!
- 亚瑟阿伦的三十六个问题。
- uniapp的uni.compressImage压缩图片的巨坑
- 基于Azure Kinect SDK获取物体rgb图、深度图、红外IR图和点云数据并保存到本地
- 前端HTML调用jQuery库,属性操作:更换图片、添加字体样式(前端:HTML搭配jQuery系列教程六)
- Ubuntu 20.04 美化终端
热门文章
- Raki的读paper小记:A Unified MRC Framework for Named Entity Recognition
- SpringBoot 2.0 整合Mybatis详细步骤
- javascript事件委托和jQuery事件绑定on、off 和one以及on绑定多个事件(重要)
- Spring AOP之静态代理
- AWK相关学习(转)
- 安腾机器IA64 全自动网络安装Linux - elilo+kickstart
- MSSQL存储过程调用 C#DLL
- idea64.exe.vmoptions 参数意义
- redis info信息注解
- 垃圾回收相关算法总结