算法 离散化

整数离散化

适用条件

  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;
        else
            l = 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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

等保——密评技术要求

密评简介 密评定义&#xff1a;全称商用密码应用安全评估, 是指对采用商用密码技术、产品和服务集成建设的网络和信息系统密码应用的合规性、正确性、有效性进行评估。密评对象&#xff1a;重要信息系统、关键信息基础设施、网络安全等保三级及以上的系统。评测依据&#xff1…

算法通关村-----数据流的中位数

数据流的中位数 问题描述 中位数是有序整数列表中的中间值。如果列表的大小是偶数&#xff0c;则没有中间值&#xff0c;中位数是两个中间值的平均值。 例如 arr [2,3,4] 的中位数是 3 。 例如 arr [2,3] 的中位数是 (2 3) / 2 2.5 。 实现 MedianFinder 类: MedianFin…

Photoshop Elements 2023 v21.0(ps简化版)

Photoshop Elements 2023是一款ps简化版图像处理软件&#xff0c;它加入了一些新的功能和工具&#xff0c;以帮助用户更高效地处理图片。 新功能&#xff1a;软件加入了黑科技&#xff0c;采用Adobe Sensei AI技术&#xff0c;主打人工智能&#xff0c;一键P图&#xff0c;新增…

Haskell 安装 Cairo

背景 Haskell 项目需要使用到柱状图&#xff0c;折线图等&#xff08;demo 代码&#xff09; 步骤&#xff08;默认已安装 stack, cabal, ghcup&#xff09; nameversionstack2.11.1cabal3.8.1.0ghcup0.1.20.0 在 package.yaml 中添加所需依赖 Chart 和 Chart-cairo name:…

查看当前目录下文件数量

查看当前目录下文件数量 查看文件夹数量查看文件数查看所有文件&#xff08;包括子文件&#xff09;数量查看所有目录&#xff08;包括子目录&#xff09;数量查看图片数量 查看文件夹数量 ls -l | grep ^d | wc -l查看文件数 不包含文件夹 ls -l | grep ^- | wc -l查看所有…

Selenium 学习(0.17)——软件测试之测试用例设计方法——白盒测试——逻辑覆盖法(条件覆盖和条件判定覆盖)

条件覆盖 设计测试用例&#xff0c;使每个判断中每个条件的可能取值至少满足一次。 条件判定覆盖 通过设计足够的测试用例&#xff0c;满足如下条件&#xff1a; 所有条件的可能至少执行一次的取值 所有判断的可能结果至少执行一次 条件判定覆盖同时满足判定覆…

springcloud nacos配置优先级研究及配置管理最佳实践

目录 背景工具版本SpringCloud配置存放位置及相应优先级代码中nacosjar包外挂 多种配置共同存在时的优先级项目配置管理最佳实践无nacos的情况有nacos的情况 参考文献 背景 公司有很多应用是基于SpringBoot/SpringCloud开发。由于在配置文件中经常会涉及数据库账号密码之类的敏…

【Java学习笔记】73 - 正则表达式

项目代码 https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter27/src/com/yinhai/regexp 一、引入正则表达式 1.提取文章中所有的英文单词 2.提取文章中所有的数字 3.提取文章中所有的英文单词和数字 4.提取百度热榜标题 正则表达式是处理文本的利器…

【ShardingSphere专题】SpringBoot整合ShardingSphere(一、数据分片入门及实验)

目录 前言阅读对象笔记正文一、ShardingSphere介绍1.1 ShardingSphere-JDBC&#xff1a;代码级别1.2 ShardingSphere-Proxy&#xff1a;应用级别1.3 横向对比图 二、ShardingSphere之——数据分片2.1 基本介绍2.2 分片的形式2.2.1 垂直分片2.2.2 水平分片 2.3 数据分片核心概念…

JavaWeb后端数据库MySQL的使用

JavaWeb MySQLSQL数据库设计 多表设计1对多1对1多对多 多表查询连接查询内连接外连接左外连接右外连接 子查询事务索引 MySQL MySQL数据模型 关系型数据库&#xff1a;建立在关系模型基础上&#xff0c;由多张相互连接的二维表组成的数据库。 SQL SQL&#xff1a;操作关系型数…

【读论文】【泛读】S-NERF: NEURAL RADIANCE FIELDS FOR STREET VIEWS

文章目录 0. Abstract1. Introduction2. Related work3. Methods-NERF FOR STREET VIEWS3.1 CAMERA POSE PROCESSING3.2 REPRESENTATION OF STREET SCENES3.3 DEPTH SUPERVISION3.4 Loss function 4. EXPERIMENTS5. ConclusionReference 0. Abstract Problem introduction&…

井盖倾斜怎么办?智能井盖传感器监测方法

井盖倾斜是一个紧迫的问题&#xff0c;如果不及时处理可能会导致道路安全性下降&#xff0c;进而增加车辆和行人发生意外的风险。为应对这一问题现已开发出智能井盖传感器&#xff0c;它可以持续监测井盖的状态&#xff0c;一旦发现倾斜等异常情况会立即发出警报。 在智慧城市的…

前端---JavaScript篇

1. 介绍 JavaScript 是 前端开发人员必须学习的 3 门语言中的一门&#xff1a; HTML 定义了网页的内容CSS 描述了网页的布局JavaScript 控制了网页的行为 接下来开始详解JavaScript。 2.引入方法 js有两种导入方式&#xff0c;一种是内部脚本&#xff1a;直接在html页面中…

csv文件EXCEL默认打开乱码问题

这里讨论的问题是&#xff0c;当用记事本打开带有中文字符的csv正常时&#xff0c;用excel打开却是乱码。 简单概括就是&#xff1a;编码问题&#xff0c;windows的 excel打开csv文本文件时&#xff0c;默认使用的是系统内的ANSI&#xff0c;在中文环境下就是GB2312。如果写文件…

NX二次开发UF_MTX3_vec_multiply_t 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_MTX3_vec_multiply_t Defined in: uf_mtx.h void UF_MTX3_vec_multiply_t(const double vec [ 3 ] , const double mtx [ 9 ] , double vec_product [ 3 ] ) overview 概述 Ret…

C#,数值计算——插值和外推,径向基函数插值(RBF_inversemultiquadric)的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { public class RBF_inversemultiquadric : RBF_fn { private double r02 { get; set; } public RBF_inversemultiquadric(double scale 1.0) { this.r02 Globals.SQR(scale); …

nginx 配置跨域(小皮面板)

本地开发的时候&#xff0c;前端请求后端&#xff0c;后端不能用域名请求&#xff0c;只能用端口模式&#xff0c;在小皮面板的话就是如下配置&#xff1a; 我的测试项目部署&#xff1a; 前端&#xff1a;http://localhost:8082 后端&#xff1a;http://localhost:8081 前端…

【小黑嵌入式系统第十课】μC/OS-III概况——实时操作系统的特点、基本概念(内核任务中断)、与硬件的关系实现

文章目录 一、为什么要学习μC/OS-III二、嵌入式操作系统的发展历史三、实时操作系统的特点四、基本概念1. 前后台系统2. 操作系统3. 实时操作系统&#xff08;RTOS&#xff09;4. 内核5. 任务6. 任务优先级7. 任务切换8. 调度9. 非抢占式&#xff08;合作式&#xff09;内核10…

C陷阱与缺陷——第2章语法陷阱

1. 理解函数声明 硬件将调用首地址为0位置的子例程 (*(void(*)())0)(); 任何C变量的声明都由两部分组成&#xff1a;类型以及一组类似表达式的声明符&#xff0c;声明符从表面看与表达式有些类似&#xff0c;对它求值应该返回一个声明中给定类型的结果。 假定变量fp是一个函…

UData+StarRocks在京东物流的实践 | 京东物流技术团队

1 背景 数据服务与数据分析场景是数据团队在数据应用上两个大的方向&#xff0c;行业内大家有可能会遇到下面的问题&#xff1a; 1.1 数据服务 烟囱式开发模式&#xff1a;每来一个需求开发一个数据服务&#xff0c;数据服务无法复用&#xff0c;难以平台化&#xff0c;技术…