算法 离散化

整数离散化

适用条件

  1. 适用于有序的整数序列
  2. 该序列的值域很大,该序列的数的个数很少
  3. 使用的是数的相对大小而非绝对大小

算法思路

原数组 a :

数组下标:0 1 2 3 4

数组元素:1 2 2 5 109

映射数组 :

数组下标:0 1 2 3

数组元素:0 1 2 3(从0开始映射)

1 2 3 4(从1开始映射)

原理

  1. 将数据从数组a中复制到b数组,对b排序
  2. 给b去重
  3. 将b的下标作为象征,将a数组每个元素使用二分查找在b中找到,并用b的下标值替换a数组的元素值。

这样就完成了离散化操作

存在的问题

  1. a 数组中可能存在重复的元素 去重
  2. 如何算出 a 数组中每个元素离散化后的值 二分

其实就是找出在 a 数组中的下标是多少

模板

C

#include<studio.h>

int main()

{

int a[100]={0};

int n;

scanf("%d",&n);

for(int i=0;i<n;i++)

scanf("%d",&a[i]);

for(int j=0;j<n-1;j++){

for(int k=0;k<n-j-1;k++){

if(a[k]>a[k+1]){

int t=a[k];

a[k]=a[k+1];

a[k+1]=t;

}

}

}

int i=0,j=1;

int len=n;

while(i>=len-1 && j>=len-1){

while(a[i]!=a[j] && j<len){

i=j;

j++;

}

while

}

C++

需去重

vector<int> alls; //存储所有待离散化的值

sort(alls.begin(),alls.end()); //将数组中所有值排序

alls.erase(unique(alls.begin(),alls.end()),alls.end()); //去掉重复元素

//unique()函数将数组中所有元素去重,并且返回去重之后数组的尾端点的下标,erase()函数将返回的尾端点和数组末尾之间的数据去掉

int find(int x) //用二分求出x对应的离散化的值,找到第一个>=的位置(从左往右找)

{

int l=0,r=alls.size()-1;

while(l<r)

{

int mid=l+r>>1;

if(alls[mid]>=x)

r=mid;

else

l=mid+1;

}

return r+1; //返回下标,r+1 表示从1开始映射,r 表示从0开始映射

}

具体参考下面区间和例题

无需去重

一边插入一边映射,类似于用二分优化插入排序。

使用插入排序方法,将数轴上的位置的相对大小作为判断依据进行排序,在每次接收时对数据进行同步处理,从第二个接收开始,先查看在该数组中,是否对此位置进行过操作,用二分查找进行判断,如果有,直接在对应位置上的数值进行增加,如果没有,使用插入排序中的插入操作把该数据直接插入数组中,这样的话,对于整个数组就不会有重复位置,即在数轴上没有相同的位置,因为会先进行查找,如果发现对某个位置已经进行过操作时,直接将其数值增加。所以在整个数组中没有一个相同的在数轴上的位置,并且是按照相对大小进行排序的,始终是有序的。

如何实现unique()函数

返回值

返回的是一个vector<int>的迭代器

基本实现思路:双指针算法

什么样的元素是不同的:排好序之后,1.它是第一个元素 2.a[i]!=a[i-1]

代码

vector<int>::iterator unique(vector<int> &a)

{

int j=0;//存下当前存到第几个数,j <= i

for(int i=0;i<a.size();i++)//遍历所有的数

if(!i || a[i]!=a[i-1])

a[j++]=a[i];//a[0]~a[j-1]就是所有a中不同的数

return a.begin()+j;

}

例题:区间和

假定有一个无限长的数轴,数轴上每个坐标上的数都是0。

现在,我们首先进行 n 次操作,每次操作将某一位置x上的数加c。

接下来,进行 m 次询问,每个询问包含两个整数l和r,你需要求出在区间[l, r]之间的所有数的和。

输入格式

第一行包含两个整数n和m。

接下来 n 行,每行包含两个整数x和c。

再接下里 m 行,每行包含两个整数l和r。

输出格式

共m行,每行输出一个询问中所求的区间内数字和。

数据范围

−10e9≤x≤10e9,

1≤n,m≤10e5,

−10e9≤l≤r≤10e9,

−10000≤c≤10000

输入样例

3 3

1 2

3 6

7 5

1 3

4 6

7 8

输出样例

8

0

5

当数组下标比较小的时候(数据范围比较小),可以用前缀和来完成

当数据范围比较大的时候,用离散化来完成

代码

//读入所有操作,将用到的位置进行离散化
#include<iostream>
#include<vector>  
#include<algorithm>
using namespace std;
typedef pair<int, int> PII;   //PII将两个数绑定在一块,一个作为first,一个作为second
const int N = 300010;//插入操作是十万(n),查询操作是二十万(2m)
int n, m;
int a[N], s[N]; //a是用到的数组成的数组,s是前缀和数组
vector<int> alls;  //说明里面存储的是int类型,相当于一个int类型的数组,不用考虑数组长度,alls存的是所有用到的下标
vector<PII> add, query;//插入操作,是pair<int,int>类型的数组,add和query是名称
int find(int x) //求x的值离散化之后的结果,求所用到位置(x)离散化之后的值//其实就是对于排序、去重之后的alls数组(所有用到的位置),返回x的下标(从0算起)/下标+1(从1算起)
{int l = 0, r = alls.size() - 1; //size是返回vector中有多少个有效数据while (l < r){int mid = (l + r) >> 1;if (alls[mid] >= x)r = mid;elsel = mid + 1;}return r + 1;//映射到从1开始的自然数
}
int main()
{cin >> n >> m;for (int i = 0;i < n;i++){int x, c;cin >> x >> c;add.push_back({ x,c }); //向vector末尾加数据,调用pair类型alls.push_back(x); //所有的点放在alls中,包括数字的点和区间的点}for (int i = 0;i < m;i++){int l, r;cin >> l >> r;query.push_back({ l, r }); //每次询问的左端点和右端点放在query中alls.push_back(l);alls.push_back(r);}//去重sort(alls.begin(), alls.end());//排序,指向数组数组首元素的指针,指向数组末尾元素后一位指针,第三个是一个函数指针,也可以是函数对象【在类中对()进行重载】,仿函数,类似于函数,第三个参数用来制定排序规则alls.erase(unique(alls.begin(), alls.end()), alls.end());//unique()把数组中所有重复元素删去,把不重复的元素放到数组的前面,//返回的是新数组的一个最后位置,把新数组最后一个位置到原来数组末尾的数据删除,即去重//处理插入//erase()用来删除//处理插入for (auto item : add){int x = find(item.first); //求所用到的位置离散化之后的值a[x] += item.second;}//预处理前缀和for (int i = 1;i <= alls.size();i++)s[i] = s[i - 1] + a[i];//处理询问for (auto item : query){int l = find(item.first), r = find(item.second);cout << s[r] - s[l - 1] << endl;}return 0;
}

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

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

相关文章

Flask教程入门

1.学习Flask之前&#xff0c;首先需要对URL进行一定的了解。 URL的一些知识&#xff1a; 1.URL只能包含ASCII码里面一些可显示的字符&#xff0c;如A-Z&#xff0c;a-z&#xff0c;0-9&#xff0c;&&#xff0c;#&#xff0c;%&#xff0c;&#xff1f;&#xff0c;/等字符…

数据链路层——以太网协议、ARP协议

目录 以太网协议 以太网协议的简介 以太网协议所处的位置 以太网帧&#xff08;或者说MAC帧&#xff09;的格式 局域网通信原理 碰撞避免算法&#xff08;包含MTU的知识点&#xff09; 局域网攻击原理 ARP协议 ARP协议所在的位置 为什么要存在ARP协议&#xff08;或者…

nodejs669在线图书借阅管理系统vue前端

系统的设计与实现主要实现角色有管理员和用户,管理员在后台管理用户模块、用户表模块、图书借阅模块、图书归还模块、图书分类模块、token表模块、收藏表模块、书籍信息模块、图书资讯模块、留言板模块、书籍信息评论表模块、注册用户模块、配置文件模块、处罚记录模块、在线客…

CC++内存对齐

说明 在C语言中&#xff0c;内存对齐是一种优化技术&#xff0c;用于提高数据访问的速度并降低CPU的内存存取时间。内存对齐主要针对结构体、联合体等数据结构&#xff0c;编译器会自动将数据对齐到其自然对齐字节的整数倍的位置。 C语言中内存对齐遵循以下规则&#xff1a; …

Mysql更新Blob存储的Josn数据

Mysql更新blob存储的Josn数据 记录一次mysql操作blob格式存储的json字符串数据 1、检查版本 -- 版本5.7以上才可以能执行json操作 select version(); 2、创建测试数据 -- 创建测试表及测试数据 CREATE TABLE test_json_table AS SELECT UUID(), {"test1": {"…

Java---权限修饰符、final、static

文章目录 1. 权限修饰符2. final(最终态)3. static(静态) 1. 权限修饰符 修饰符同一个类中同一个包中的子类和无关类不同包的子类不同包的无关类private√默认√√protected√√√public√√√√ 2. final(最终态) 1. final关键字是最终的意思&#xff0c;可以修饰成员方法、…

MATLAB基础应用精讲-【数模应用】漫谈深度学习

目录 几个高频面试题目 传统CV和深度学习方法的比较 DL和传统计算机视觉的比较

langchain实战笔记系列

最近因工作需要&#xff0c;需要做一下ChatGLM的技术验证&#xff0c;主要是基于langchain进行学习&#xff0c;以此系列记录一下实战过程。 以下是系列文章&#xff1a; Langchain-Chatchat-win10本地安装部署成功笔记&#xff08;CPU&#xff09;-CSDN博客 Win10系统下tor…

OpenCV数字图像处理——检测出图像中的几何形状并测量出边长、直径、内角

一、简介 在传统的自动化生产尺寸测量中&#xff0c;常用的方法是利用卡尺或千分尺对被测工件的某个参数进行多次测量&#xff0c;并取这些测量值的平均值。然而&#xff0c;这些传统的检测设备或手动测量方法存在着一些问题&#xff1a;测量精度不高、测量速度缓慢&#xff0…

【单调栈】最大二叉树

题目&#xff1a; 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&#xff0c;其值为 nums 中的最大值。递归地在最大值 左边 的 子数组前缀上 构建左子树。递归地在最大值 右边 的 子数组后缀上 构建右子树。 返回 nums…

python 爬虫之 爬取网站信息并保存到文件

文章目录 前期准备探索该网页的HTML码的特点开始编写代码存入文件总的程序文件存储效果 前期准备 随便找个网站进行爬取&#xff0c;这里我选择的是(一个卖书的网站&#xff09; https://www.bookschina.com/24hour/62700000/ 我的目的是爬取这个网站的这个页面的书籍的名称以…

git打tag和版本控制规范

我们在开发中经常会遇到要打tag的情况&#xff0c;但这个tag应该如何打呢&#xff1f;我不知道大家平时是怎么打的&#xff0c;但我基本就是从1.0.0开始进行往上递增&#xff0c;至于如何递增&#xff0c;基本凭感觉。今天同事新打了一个tag进行发版&#xff0c;然后被架构点名…

佳易王个体诊所管理系统电子处方软件,个体诊所人员服务软件,卫生室配方模板电子病历系统教程

佳易王个体诊所管理系统电子处方软件&#xff0c;个体诊所人员服务软件&#xff0c;卫生室配方模板电子病历系统教程 软件试用版下载可以点击最下方官网卡片 软件功能&#xff1a; 1、配方模板&#xff1a;可以自由添加配方分类&#xff0c;预先设置药品配方&#xff0c;可以…

【赠书第9期】巧用ChatGPT高效搞定Excel数据分析

文章目录 前言 1 操作步骤 1.1 数据清理和整理 1.2 公式和函数的优化 1.3 图表和可视化 1.4 数据透视表的使用 1.5 条件格式化和筛选 1.6 数据分析技巧 1.7 自动化和宏的创建 2 推荐图书 3 粉丝福利 前言 ChatGPT 是一个强大的工具&#xff0c;可以为你提供在 Exce…

【nlp】4.5 迁移学习实践项目(相关概念、中文分类、填空、句子关系、模型微调)

迁移学习实践项目 1 迁移学习1.1 定义与基本思想1.2 迁移学习的基本概念1.3 迁移学习的类型1.4 迁移学习的应用1.5 迁移学习的优势1.6 迁移学习的缺点1.7 迁移学习有关概念1.7.1 预训练模型(Pretrained model)1.7.2 微调(Fine-tuning)1.7.3 两种迁移方式2 迁移学习项目实战说明…

【SA8295P 源码分析】135 - QNX 以太网 iperf3 上行带宽吞吐量低的问题分析优化

【SA8295P 源码分析】135 - QNX 以太网 iperf3 上行带宽吞吐量低的问题分析优化 一、QNX 上行、下行吞吐量测试结果1.1 QNX 上行吞吐量带宽测试:200Mbps (偏差,需分析)1.2 QNX 下行吞吐量带宽测试:752Mbps (勉强达标,需优化)二、优化方法:关闭调试模块,开启QNX 最大性…

Flask使用SQLAlchemy数据库报错 RuntimeError:working outside of application context.处理

报错处理&#xff1a; http://www.manongjc.com/detail/42-oeqrsqzbiaxaelw.html https://blog.csdn.net/qq_41286373/article/details/129280569 将如下两个插件版本改为如下版本即可&#xff1a; Flask-SQLAlchemy 2.5.1 SQLAlchemy 1.4.39

Mysql中的引擎介绍(InnoDB,MyISAM,Memory)

MySQL引擎就是指表的类型以及表在计算机上的存储方式。 MySQL数据库及其分支版本主要的存储引擎有三种&#xff0c;分别是 InnoDB、MyISAM、 Memory&#xff0c;还有一些其他的&#xff0c;CSV、Blackhole等&#xff0c;比较少见&#xff0c;可以使用SHOW ENGINES语句来查看。结…

【Python 训练营】N_13 遍历字符串

题目 将字符串生成迭代器&#xff0c;逐个访问字符串中每个字符&#xff0c;并大写合并输出。 分析 字符串转换迭代器&#xff0c;for循环遍历字符串。 答案 # 方法一 s1 Python l [] for i in iter(s1): # 使用iter()函数生成迭代器l.append(i.upper()) print(.join(l)…

Linux DNS服务器相关命令

配置文件&#xff1a; /etc/dnsmasq.conf ### 可以添加修改 address IP 与自定义域名 的对应关系 修改后重启服务&#xff1a;systemctl restart dnsmasq dns服务其他指令&#xff1a; systemctl start dnsmasq systemctl stop dnsmasq systemctl enable dnsmasq ## 开机自启已…