离散化思想详解

【离散化】图形面积 桌面上放了N个平行于坐标轴的矩形,这N个矩形可能有互相覆盖的部分,求它们组成的图形的面积。 阅读详情


前言

当有效数据量可控,但数值落在的数值空间非常大的时候,离散化思想就可以派上用场了。


一、引入例题

题目描述

  • 桌面上放了N个平行于坐标轴的矩形,这N个矩形可能有互相覆盖的部分,求它们组成的图形的面积。

输入格式

  • 输入第一行为一个数N (1≤N≤100),表示矩形的数量。下面N行,每行四个整数,分别表示每个矩形的左下角和右上角的坐标,坐标范围为 − 1 0 4 -10^4 −104 到 1 0 4 10^4 104 之间的整数。

输出格式

  • 输出只有一行,一个整数,表示图形的面积。

分析

  每输入一个矩形的时候,在这个矩形的位置填充 true,最后再相加。这个时候不加优化的 暴力 最坏的情况下这个时候空间复杂度大概为 O ( 4 × 1 0 8 ) O(4\times10^8) O(4×108),这还是可以接受的,代码如下: 这里很好理解我就不解释啦QAQ
零优化暴力

#include<cstdio>
#include<algorithm>
using namespace std;
bool map[1001][1001];
int n,x1,y1,x2,y2,xx,yy,ans;
int main(){
	scanf("%d",&n);
	for(int i=0;i<n;i++) {
		scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
		if(x1>x2)swap(x1,x2);
		if(y1>y2)swap(y1,y2);
		xx=max(xx,x2);
		yy=max(yy,y2);
		for(int x=x1;x<=x2;x++)
			for(int y=y1;y<=y2;y++)
				map[x][y]=1;
	}
	for(int x=0;x<=xx;x++)
		for(int y=0;y<=yy;y++)
			ans=ans+map[x][y];
	printf("%d",ans);
	return 0;
}

但是如果题目将坐标范围扩大到 − 1 0 8 -10^8 −108 到 1 0 8 10^8 108 的话时间和空间都会爆掉, 暴力不可解 。

优化

时间

  从时间的角度来优化的话,我们可以通过批量的填充来节约时间,也就是说将整个大的矩形转化成小的矩形:(虽然实际情况可能并不是这样)
分割
若每次这样填充,在最后遍历的时候,时间效率会大大提高。

空间

  从空间角度来看,我们可以直接储存每个小块,再储存他们的面积:
优化后
此时所需要的空间由原来的 7 × 10 7\times10 7×10 变成了 2 × 4 × 4 2\times4\times4 2×4×4。哇,你真了不起
这里附上代码:

//矩形覆盖,离散化处理 
#include<cstdio>
#include<algorithm>
#define nn 1001
using namespace std;
struct aty{
	int x1,x2,y1,y2;
} a[nn];
struct bty{
	long long  N,xy;
}b[2*nn],c[2*nn];
bool cmp(bty a,bty b){ return a.xy<b.xy;}
long long xx[nn],yy[nn],x1,y1,x2,y2,nowx,nowy,ans; 
bool map[201][201];
int n,newx,newy;
int main(){
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2);
		b[i].N=b[n+i].N=c[i].N=c[i+n].N=i;
		b[i].xy=x1;b[i+n].xy=x2;
		c[i].xy=y1;c[i+n].xy=y2;		
	}
	sort(b+0,b+2*n,cmp);
	sort(c+0,c+2*n,cmp);	// 排序完后用下标代替左右x、y的值 
	for(int i=0;i<2*n;i++){
		if(nowx!=b[i].xy) nowx=b[i].xy,newx++,xx[newx]=nowx;
		if(a[b[i].N].x1==0) a[b[i].N].x1=newx;
		else a[b[i].N].x2=newx;		
		if(nowy!=c[i].xy) nowy=c[i].xy,newy++,yy[newy]=nowy;
		if(a[c[i].N].y1==0) a[c[i].N].y1=newy;
		else a[c[i].N].y2=newy;
	}
	for(int i=0;i<n;i++){
		for(int x=a[i].x1+1;x<=a[i].x2;x++)
			for(int y=a[i].y1+1;y<=a[i].y2;y++)
				map[x][y]=1;
	}
	for(int x=2;x<=newx;x++)
		for(int y=2;y<=newy;y++)
			if(map[x][y]==1)
				ans+=(xx[x]-xx[x-1])*(yy[y]-yy[y-1]);
	printf("%d",ans);
	return 0;
}

优化总结

经过时间和空间的优化,这道题的时间成本就可以降到可以接受的程度,而这种优化思想,就叫做离散化思想。

二、离散化思想总结

概述

  • 离散化,就是把无限空间中有限的个体映射到有限的空间中去,以提高算法的时空效率。
  • 很多算法的复杂度与数据中的最大值有关,比如用数组实现的一对一标记。时常会遇到这种情况:数据的范围非常大或者其中含有负数,但数据本身的个数并不是很多(远小于数据范围)。在这种情况下,如果每个数据元素的具体值并不重要,重要的是他们之间的大小关系的话,我们可以先对这些数据进行离散化,使数据中的最大值尽可能小且保证所有数据都是正数。

预期功能

  离散化的原理和实现都很简单。为了确保不出错且尽可能地提高效率,我们希望离散化能实现以下几种功能:
1.保证离散化后的数据非负且尽可能的小
2.离散化后各数据项之间的大小关系不变,原本相等的也要保持相等。
由此,找出数据项在原序列中从小到大排第几就是离散化的关键。

思路

可以通过下面的方法以O(nlogn)的时间复杂度完成离散化,n为序列长度。
1.对原序列进行排序,使其按升序排列。
2.去掉序列中重复的元素。
3.此时序列中各位置的值和位置的序号就是离散化的映射方式。

例题

这里有一个小小的题目很好的体现了离散化思想:

  • 例如:对于序列105,35,35,79,-7,排序并去重后变为-7,35,79,105,由此就得到了对应关系-7->1, 35->2, 79->3, 105->4。
int n, a[maxn], t[maxn];
//这里以下标1为序列的起点,一般情况下从0开始也可以
for(int i = 1;i <= n;i++){
    scanf("%d", &a[i]);
    t[i] = a[i];//t是一个临时数组,用来得到离散化的映射关系
}
//下面使用了STL中的sort(排序),unique(去重),lower_bound(查找)函数
sort(t + 1, t + n + 1);//排序
int m = unique(t + 1, t + 1 + n) - t - 1;//去重,并获得去重后的长度m
for(int i = 1;i <= n;i++){
    a[i] = lower_bound(t + 1, t + 1 + m, a[i]) - t;//通过二分查找,快速地把元素和映射对应起来
}

总结

  实际上这非常好理解QAQ,所以…我先溜啦,芜湖~。

进阶数据结构——离散化 核心总结离散化是一种将连续数据映射到离散值的技术,适用于处理大规模或稀疏数据。通过排序、去重和映射,可以高效实现离散化。学习建议分类刷题:按问题类型集中练习(如区间查询、统计计数、几何问题)。理解算法原理:掌握离散化的实现步骤和优化技巧。手写模拟过程:在纸上模拟离散化的过程,加深直观理解。!! 阅读详情

相关推荐

离散化思想——只处理有效数据的优化思想

离散化思想可以理解为“只处理有效数据”的一种思想,对于问题的模型进行结构重建基本参考坐标是离散化代码实现的常见方法。对于数值范围巨大而实际有效点较少的问题可以采用离散化转化为更容易实现的问题求解。你可以想象一下,如果你有NNN根很长的绳子,你把它们交叉着叠在一起(有重叠部分也有没有绳子的部分),已知每根绳子的头和尾,你想知道这些绳子的覆盖长度,那你只能慢慢的量。

小天狼星_布莱克 的博客 309

图形面积(离散化)

图形面积 Description 桌面上放了N个平行于坐标轴的矩形,这N个矩形可能有互相覆盖的部分,求它们组成的图形的面积。 Input 输入第一行为一个数N(1≤N≤100),表示矩形的数量。下面N行,每行四个整数,分别表示每个矩形的左下角和右上角的坐标,坐标范围为–108到108之间的整数。 Output 输出只有一行,一个整数,表示图形的面积。 Sample Input 3 1 1 4 3 2 -1 3 2 4 0 5 2 Sample Output 10 题目分析+解题思路 平常的想法就是开一个与二

我很菜的好吧 878

用AG9311芯片DIY一个多功能Type-C扩展坞:从原理图到PCB布局的保姆级指南

本文详细介绍了如何利用AG9311芯片DIY多功能Type-C扩展坞,涵盖从原理图设计到PCB布局的全过程。AG9311芯片作为高性价比的Type-C控制器,支持HDMI 2.0、USB 3.0、PD快充和千兆网口,适合硬件爱好者打造个性化扩展坞。文章还提供了调试技巧和进阶优化建议,帮助读者轻松完成项目。

weixin_42520909的博客 404

图形面积

Description 桌面上放了N个平行于坐标轴的矩形,这N个矩形可能有互相覆盖的部分,求它们组成的图形的面积。 Input 输入第一行为一个数N(1≤N≤100),表示矩形的数量。下面N行,每行四个整数,分别表示每个矩形的左下角和右上角的坐标,坐标范围为–108到108之间的整数。 Output 输出只有一行,一个整数,表示图形的面积。 Sample Input 3 1 1 4 3 2 -1 ...

Beautiful women in tights 324

稳定性仿真(stb闭环增益仿真)

stb仿真主要是测试电路的稳定性,例如运放在闭环电路中的增益和相位裕度的值,从而判别电路是否正常工作。 以下是stb仿真的过程: (1)调用iprobe器件 从analogLib中调iprobe器件,通过器件中的箭头标识确定接入电路的方法,箭头起点端连运放的输出端,箭头的终点端连在反馈环路的作用端。iprobe器件连入电路后相当于理想导线。(iprobe器件连接在反馈回路上) (2)analyses设置 勾选stb和frequency,此处的频率范围设置在0.1~1GHz,Probe Instance/T

qq_36686804的博客 3万+

PostgreSQL+PostGIS空间数据入库实战:从矢量栅格到GeoServer发布全流程

本文详细介绍了将矢量与栅格空间数据导入PostgreSQL并利用PostGIS扩展进行管理的完整流程。内容涵盖环境搭建、使用shp2pgsql和raster2pgsql工具进行数据入库、基础空间查询验证,以及最终通过GeoServer发布为地图服务的实战步骤,为构建空间数据平台提供清晰指引。

weixin_29268267的博客 289

Vijos P1056 图形面积

矩形面积并

我要吃熊猫 714

IIR数字滤波器原理,设计方法及嵌入式应用

基于STM32的二阶直接II型巴特沃斯低通滤波器设计方法及应用

weixin_38342580的博客 1万+

[VIJOS1056]图形面积

描述桌面上放了N个平行于坐标轴的矩形,这N个矩形可能有互相覆盖的部分,求它们组成的图形的面积。输入格式输入第一行为一个数N(1≤N≤100),表示矩形的数量。下面N行,每行四个整数,分别表示每个矩形的左下角和右上角的坐标,坐标范围为–10^8到10^8之间的整数。输出格式输出只有一行,一个整数,表示图形的面积。样例输入3 1 1 4 3 2 -1 3 2 4 0 5 2 样例输出10 题解:我们先将

dxyinme-Zz 743

手把手实现STM32+ESP8266+原子云服务器+手机APP应用——第一节-ATK-ESP8266 WIFI模块通过USB-TTL实现连接原子云服务器与手机APP互相通信

本节实现ATK-ESP8266 WIFI模块通过USB-TTL实现连接原子云服务器与手机APP通信。具体来说,本节使用串口CH340(USB-TTL)连接正点原子ATK-ESP8266 WIFI模块,通过AT命令实现连接原子云服务器与手机APP互相通信,实现硬件设备(WIFI模块)与云服务器和手机APP的互相通信。后面章节不用串口CH340(USB-TTL),通过编写单片机程序实现数据远程互相通信,并介绍手机APP的程序设计。单片机任意款即可,STM32F1系列,F4系列,H系列等都可以。本系列为(手把手实

嵌入式阿齐Archie 8419

【51单片机实物】基于51单片机设计的简易直流电机调测速系统(可用在普中开发板)

功能任务描述:将设置的转速与当前测量的转速比较,得出差值用于控制DAC0832的输出电压,从而控制直流电机的转速,使转速逐渐达到设置转速。在LED上显示设置转速(左2位LED)和当前转速(右2位LED),转速显示采用十进制。控制过程中,当前转速显示不断变化。*直流电机转速范围0-96r/s,误差±1r/s

嵌入式阿齐Archie 1万+

算法基础详解(六)倍增思想与离散化思想

https://www.luogu.com.cn/problem/P1226关于如何解决存不下的问题!这里算是个取模运算的规则 !加法取模 (A+B)%MOD=((A%MOD)+(B%MOD))%MOD (A + B) \% MOD = ((A \% MOD) + (B \% MOD)) \% MOD (A+B)%MOD=((A%MOD)+(B%MOD))%MOD 乘法取模 (A×B)%MOD=((A%MOD)×(B%MOD))%MOD (A \times B) \% MOD = ((A \% MOD) \

Fcy648的博客 424

基于RK3588平台的高分辨率多摄像头系统深度优化:从48M单摄到双摄分时复用的完整解决方案

本文深入解析了RK3588平台的高分辨率摄像头实现方案。重点介绍了:1)RK3588的MIPI PHY硬件架构,包括DCPHY和DPHY的资源配置及工作模式;2)双ISP合成技术,通过并行处理提升48M高分辨率图像的处理能力;3)以OV50C40传感器为例,详细展示了48M单摄系统的硬件连接、I2C设备配置和关键参数设置。文章为开发者提供了从硬件连接到软件配置的完整技术方案,有助于实现高性能嵌入式视觉系统。

FJN110的博客 675

离散化与差分结合应用例题精讲

1.数组太大没法直接暴力2.发现排序去重可以缩小数组(离散化)3.想怎么求?4.发现对大区间差分,然后前缀和只要大于1就是被覆盖的规律5.利用4规律检测覆盖情况,再求小区间大小。

Wst_sir的博客 412

SAP 系统间 SSO 的真正价值,从 SM59 到可信 RFC 的安全设计

SAP S/4HANA系统间Single Sign-On(SSO)的核心价值在于集中管理通信身份与信任关系,而非仅减少密码输入。传统固定账号密码方式在系统规模扩大后会面临密码管理、审计追踪等挑战。通过SM59配置可信RFC目标系统,结合SSL证书或SAP Trusted System等强认证机制,能有效降低安全凭据暴露风险。SSO配置需配合授权对象、角色管理等建立清晰的信任边界,实现系统间安全通信的同时保持可审计性。这种方案特别适用于Fiori前端与S/4HANA后端等场景,通过可信RFC传递用户身份,避免

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1062

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

【基础算法】从暴力到高效:倍增和离散化,你必须掌握的两大优化神器

本文介绍了两种优化算法效率的核心思想:倍增和离散化。倍增通过分阶段扩大步长,将线性复杂度优化为对数级别,典型应用包括快速幂和64位整数乘法。离散化则将大范围稀疏数据映射到紧凑空间,避免无效计算,适用于处理数值范围大但数据量小的问题。 文章详细讲解了快速幂和64位整数乘法的算法原理与实现,通过二进制分解和倍增思想显著提升计算效率。在离散化部分,提供了排序+去重+二分查找的实现模板,并给出具体案例说明如何将原始数据映射为紧凑索引。

遇见,获得,失去,成长,释怀,完结。我与旧事归于尽,来年依旧迎花开。 382

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

算法竞赛必备:离散化核心原理与C++高效实现详解

在算法设计与数据处理中,当面对数值范围极大但实际数据点稀疏的场景时,直接使用数组等依赖连续下标的数据结构会面临内存限制的挑战。离散化作为一种核心的数据预处理思想,通过将稀疏的、大范围的原始数值映射到一个紧凑、连续的整数空间,巧妙地解决了这一矛盾。其技术原理基于排序、去重与二分查找,核心价值在于搭建了一座桥梁,使得树状数组、线段树等高效数据结构能够应用于原本因值域过大而无法直接处理的问题。这一技术在算法竞赛和工程实践中至关重要,广泛应用于区间求和、逆序对统计、扫描线求面积等高频场景。本文将以C++实现为例,深

weixin_31188927的博客 311

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

离散化及模板详解

离散化 基本思想 算法思路 模板 例题:区间和 题目分析 code

timerring的博客 2069

离散化的思想和它的两种代码与区别

离散化是什么:一些数字,他们的范围很大(0-1e9),但是个数不算多(1-1e5),并且这些数本身的数字大小不重要,重要的是这些数字之间的相对大小(比如说某个数字是这些数字中的第几小,而与这个数字本身大小没有关系,要的是相对大小)(6 8 9 4 离散化后即为2 3 4 1)(要理解相对大小的意思)(6在这4个数字中排第二小,那么就把6离散化成2,与数字6本身没有关系, 8,9,4亦是如此)(2...

Accepted 1万+

离散化:两种离散化方式详解

引入 离散化,就是把一些很离散的点给重新分配。 举个例子,如果一个坐标轴很长(&amp;gt;1e10),给你1e4个坐标,询问某一个点,坐标比它小的点有多少。 很容易就知道,对于1e4个点,我们不必把他们在坐标轴上的位置都表示出来,因为我们比较有多少比它小的话,只需要知道他们之间的相对大小就可以,而不是绝对大小,这,就需要离散化。 而离散化又分为两种,分为的两种是对于重复元素来划分的。第一种是重...

曹老师 5万+

离散化

概念 离散化(Discretization),把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。通俗的说,离散化是在不改变数据相对大小的条件下,对数据进行相应的缩小。例如: 原数据:1, 999, 100000, 15;处理后:1,3,4,2。 原数据:{100, 200},{20, 50000},{1, 400};处理后:{3,4},{2,6},{1,5}。 有的时候,我...

努力中的老周的专栏 1万+

C++ 离散化 算法 (详解)+ 例题

接下来,进行 m 次询问,每个询问包含两个整数 l 和 r,你需要求出在区间 [l,r] 之间的所有数的和。通俗的说,离散化是在不改变数据相对大小的条件下,对数据进行相应的压缩。例如:值域:1~10^9, 个数:10^5,值域很大,但是用到个数相对很少,这个时候就可以离散化。现在,我们首先进行 n 次操作,每次操作将某一位置 x 上的数加 c。注意:对于上述第三条,可以理解为去找这个数映射后的数组下标。假定有一个无限长的数轴,数轴上每个坐标上的数都是 00。共 m行,每行输出一个询问中所求的区间内数字和。

m0_67717626的博客 7991

离散化思想详细讲解

1.什么是离散化 数据离散化是一个非常重要的思想。 为什么要离散化?当以权值为下标的时候,有时候值太大,存不下。 所以把要离散化的每一个数组里面的数映射到另一个值小一点的数组里面去。 打个比方,某个题目告诉你有104个数,每个数大小不超过1010,要你对这些数进行操作,那么肯定不能直接开1010大小的数组,但是104的范围就完全没问题。 我们来看一下定义:离散化,把无限空间中有限的个体映射到有限的...

PengWei Yang 1121

数据离散化思想简述

数据离散化思想简述及实现 1. 离散化概述2. 应用场景3. 实现方法

Aslixzhou 1381

离散化思想

离散化是程序设计中一个非常常用的技巧,它可以有效的降低时间复杂度。其基本思想就是在众多可能的情况中“只考虑我需要用的值”。下面我将用三个例子说明,如何运用离散化改进一个低效的,甚至根本不可能实现的算法。《算法艺术与信息学竞赛》中的计算几何部分,黄亮举了一个经典的例子,我认为很适合用来介绍离散化思想。这个问题是UVA10173(http://acm.uva.es/p/v101/1...

anvt77205的博客 409
上一篇: 动态规划----背包问题(完全背包问题)
下一篇: 线段树详解(AWA)
ResCells
博客等级 码龄4年 191粉丝 26原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值