首页 > 其他分享 >一维离散化笔记

一维离散化笔记

时间:2024-10-26 16:32:34浏览次数:1  
标签:end 一维 迭代 int 元素 笔记 离散 temp 数组

一维离散化笔记

通俗来说,一维离散化就是把在无限空间中的有限元素映射到一个线性排列的区间中

举个实际的例子说明:

存在一个近似无限的空间 \([-10^9,10^9]\) ,我们需要对其中\(10^5\)个离散的元素进行操作

显然不可能对这个近似无限的区间进行\(10^5\)次遍历

所以需要把这\(10^5\)个元素映射到一个数组内

相当于缩短元素与元素之间的距离,减少遍历复杂度

这里有一个例题来具体实现这个算法:

给定一个长度为 n 的数组a,定义 rank(i) 表示数组a 中比 ai 小的不同数字个数再加 1

输入:

输入的第一行是一个整数,表示数据组数 T,接下来依次给出每组数据的信息:

第一行是一个整数,表示数列长度 n
第二行有 n个整数表示数列 a,第 i 个整数表示 ai

输出:

对每组数据,输出一行 n个整数,用空格隔开,依次表示 rank(1)到 rank(n)

备注:

\(1<=T<=5\), \(1<=n<=10^5\), \(-10^9<=a_i<=10^9\)

首先需要将输入的 ai 映射进一个数组,可以使用vector来进行这一步操作

vector<int> a,b;
int temp;
for (int i=0;i<n;i++) {
	cin>>temp;
	a.push_back(temp);
	b.push_back(temp);
}

同时需要拷贝一次 a 数组,便于进行后面的操作

然后我们对 a 数组进行排序和去重操作:

sort(a.begin(), a.end());
a.erase(unique(a.begin(), a.end()), a.end());

这里解释一下unique函数的作用:

iterator unique(iterator it_1,iterator it_2,bool MyFunc);

第一个参数为需要去重的区间的首个元素的迭代器,第二个参数为需要去重的区间的末尾元素的迭代器

然后将重复的元素移动到数组的末尾,重复操作直到迭代器移动到指定的末尾元素

返回的是不重复元素的下一个元素的迭代器

再使用erase函数擦除unique函数返回的指向重复元素的迭代器指向排序后的 a 数组末尾元素的迭代器之间的所有元素

就可以得到排序去重后的 a 数组

接下来是计算 rank(i) 的操作:该如何查找比 bi 小的不重复元素?

使用lower_bound函数可以精简的完成这个过程:

ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last,  const T& val);

函数的第一个参数为需要查找的区间的首个元素的迭代器,第二个参数为需要查找的区间的末尾元素的迭代器

第三个参数为需要查找的值

b[i] = lower_bound(a.begin(), a.end(), b[i]) - a.begin()+1;

解释这步操作:

b数组存储的是原始排列,a数组存储的是排序去重后的排列

使用lower_bound在 a数组中查找到 bi 的迭代器,再减去 a数组首个元素的迭代器得到 bi 前不重复元素的个数即rank(i)

将这个值再次赋值给 bi (节约空间),最后输出 b数组的所有元素即可AC

完整代码:

int main()
{
	int T,n,temp;
	cin >> T;
	for (int t = 0; t < T; t++) {
		vector<int> a,b;
		int temp = 0;
		cin >> n;
		for (int i = 0; i < n; i++) {
			cin >> temp;
			b.push_back(temp);
			a.push_back(temp);
		}
		sort(a.begin(), a.end());
		a.erase(unique(a.begin(), a.end()), a.end());
		for (int i = 0; i < n; i++) {
			b[i] = lower_bound(a.begin(), a.end(), b[i]) - a.begin()+1;
		}
		for (int i = 0; i < n; i++) cout << b[i] << " ";
		cout << endl;
	}
	return 0;
}

标签:end,一维,迭代,int,元素,笔记,离散,temp,数组
From: https://www.cnblogs.com/dianman/p/18504168

相关文章

  • Linux笔记---Makefile的简单用法
    1.什么是MakefileMakefile是一种用于自动化构建和管理项目的工具,特别是在软件开发中非常常见。它包含了一系列规则(rules)和指令,描述了如何编译和链接源代码文件,以及生成最终的可执行文件或库文件。简单来说,在系统中存在一个叫做make的命令,该命令被使用之后,会在当前目录下......
  • 如何选取笔记本外接显示器(以华为matebook14 2020版为例)
    选取与自己相近笔记本规格主要就是看:1、分辨率(像素):1k就是1920*1080像素,2k就是2560×1440像素,4k就是3840x2160像素、4096x2160像素;2、刷新率:就是一秒刷新多少个画面,体现在游戏流不流畅、视频卡不卡这种,例如60hz、100hz;3、连接线:看电脑的接口包含哪一些,如HDMI、USB-C(Thun......
  • VulnHub-Brainpan1 靶机笔记
    Brainpan1靶机笔记概述靶机地址:https://vulnhub.com/entry/brainpan-1,51/#download这台靶机是很好的缓冲区溢出漏洞利用的练习靶机,涉及到逆向和缓冲区溢出漏洞挖掘的一些知识。一、nmap扫描1)端口扫描nmap-sT--min-rate10000-p--oports192.168.11.12Nmapscanre......
  • 软考笔记-有向图的邻接矩阵
    软考笔记-有向图的邻接矩阵下面是2024年上半年的选择题:对下列有向图的邻接矩阵,进行深度遍历的次序是()。V1V2V3V4V5V6∞183∞∞∞∞∞5∞4∞∞∞∞∞∞∞∞15∞∞∞∞∞∞∞12∞∞∞∞∞∞∞∞A.v1-v2-v3-v4-v......
  • java计算机毕业设计笔记交易平台(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、研究背景随着数字化学习的普及,知识的传播与共享方式发生了巨大的变革。在学习和工作过程中,人们积累了大量的笔记,这些笔记蕴含着丰富的知识价值。然而,目前......
  • 24-10-21-读书笔记(二十九)-《契诃夫文集》(五)上([俄] 契诃夫 [译] 汝龙)不跟自己过不去,什
    文章目录《契诃夫文集》(五)上([俄]契诃夫[译]汝龙)不跟自己过不去,什么事情自己都过得去。目录阅读笔记总结《契诃夫文集》(五)上([俄]契诃夫[译]汝龙)不跟自己过不去,什么事情自己都过得去。  1886年之后的契诃夫是开了挂认真写短篇小说的神,之后第五卷~第十卷我应......
  • FFmpeg开发笔记(六十)使用国产的ijkplayer播放器观看网络视频
    ​ijkplayer是Bilibili公司(简称B站)基于FFmpeg3.4研发并开源的国产播放器,它可运行于Android和iOS系统,既支持播放本地视频文件,也支持播放网络上的流媒体链接。之前的文章《Linux编译ijkplayer的Android平台so库》介绍了如何编译获得App工程所需ijkplayer的so文件,接下来还要把官方......
  • 「FHQ_Treap」学习笔记
    一、前言&基本理论来自笔者的肯定:最容易理解且比较好写的平衡树(不过就是常数有点大了),可能是笔者花了较长的时间去理解旋转Treap和Splay的旋转吧()。FHQ不仅比旋转法编码简单,而且能用于区间翻转、移动、持久化等场合。——《算法竞赛》FHQ_Treap的所有操作都只用到了分......
  • 2024年工作笔记
    CMake相关CMake从基础到高级技巧#根据操作系统类型安装不同的文件if(CMAKE_SYSTEM_NAMESTREQUAL"Linux")install(FILES"linux_specific_file.conf"DESTINATIONetc)elseif(CMAKE_SYSTEM_NAMESTREQUAL"Windows")install(FILES"windows_speci......
  • 计算机网络 | 第二章 物理层 | 26王道考研自用笔记
    物理层任务:实现相邻节点之间比特(0或1)的传输2.1通信基础基本概念2.1.1信源、信宿、信号、信道在通信系统中,信源负责生成信息,信宿接收和解释信息。信号是传输信息的载体,经过信道从信源到达信宿。信道的品质直接影响到信息传输的效果。2.1.2信道的极限容量香......