常用技巧——离散化

“离散化,就是把无限空间中有限的个体映射到有限的空间中去,以提高算法的时空效率。”

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

例如,有这样一个长为5的序列:102131511,123,9813186,-611,55。其中有非常大的数以及负数,会给许多算法的实现带来困扰,我们可以把这个序列离散化,使它变成这样:5,3,4,1,2。各个元素间的大小关系没有任何改变,但数据的范围一下子就变得很舒服了。

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

可以通过下面的方法以O(nlong)的时间复杂度完成离散化,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是一个临时数组,用来得到离散化的映射关系
}
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;//通过二分查找,快速地把元素和映射对应起来
}

原文地址:https://www.cnblogs.com/sun-of-Ice/p/9419857.html

时间: 2024-10-18 18:17:53

常用技巧——离散化的相关文章

《挑战程序设计竞赛》课后练习题解集——3.2 常用技巧精选(一)

常用技巧精选(一) 尺取法 POJ 2566  给出一个长度n(<=1e5)的数列,每个数的大小在-1e4-1e4之间,给出若干询问值,要求一段字串和,它的绝对值与询问值最接近 好题目.由于数列有正有负,所以不能直接二分或尺取.考虑对前缀和排序 得到一个新数列,此时新数列任意一段子串都对应原数列的一个子串,当左右端点的下标颠倒时,字串和也会添一个负号,但是最后要取绝对值所以可以忽略.最后对新数列尺取即可 1 #include <algorithm> 2 #include <cstd

HTML5-移动开发常用技巧与弹性布局的使用

一.移动开发常用技巧 Viewport基本知识 设置布局Viewport的各种信息 1.width=device-width: 设置Viewport视口宽度等于设备宽度 2.initial-scale=1: 网页默认缩放比为1(网页在手持设备上,不会进行默认缩放 3.minimum-scale=1 网页最小缩放比为1 4.maximum-scale=1 网页最小大缩放比为1 5.user-scalable=no 禁止用户手动缩放网页(ios10+ 的设备失效) 在手机站及响应式网站的制作中,网页

【转】oracle存储过程常用技巧

原文链接 http://www.cnblogs.com/chinafine/archive/2010/07/12/1776102.html 我们在进行pl/sql编程时打交道最多的就是存储过程了.存储过程的结构是非常的简单的,我们在这里除了学习存储过程的基本结构外,还会学习编写存储过程时相关的一些实用的知识.如:游标的处理,异常的处理,集合的选择等等 1.存储过程结构 1.1 第一个存储过程 create or replace procedure proc1( p_para1 varchar2,

.Net常用技巧_导出 Excel 和相关打印设置

Excel.Application myExcel = new Excel.Application();发 表Excel.Workbook workbookData = myExcel.Application.Workbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet);Excel.Worksheet xlSheet = (Worksheet)workbookData.Worksheets[1];//取得sheet1 1) 显示当前窗口: xlSheet.

mysql 常用技巧

1.正则使用 比 LIKE 会牺牲很多的系统资源 尽量不要用 正则的语法和JS PHP 差不多 select * from t1 where email REGEXP "@163[,.]com$"; select * from t1 where email like "%@163.com" or email like "%@163,com" 2.REPLACE 函数的使用 UPDATE `v9_zhushou` SET `thumb` = REP

sqlmap常用技巧整理

言 通过在乌云网上出现的很多SQL注入漏洞,因此来总结一下,大致使用SQLMAP所遇到的参数. 基本结构 基本SQLMAP的使用方式就如下所示,使用参数式的方式,按需求添加. 12 sqlmap.py -u "http:// *" --data="a=b" -p a --level 3 --random-agent --referer="a" --technique T --dbms=mysql --cookie="cookie&quo

短线选股操作常用技巧

股票短线通常是指在一个星期或两个时期以内的时期,股票投资者只想赚取短期差价收益,而不去关注股票的基本情况,主要依据技术图表分析.一般的投资者做短线通常都是以两三天为限,一旦没有差价可赚或股价下跌,就平仓一走了之,再去买其他股票做短线.作为短线炒股,选股很重要,因为短线讲究的是一个快,快进快出,绝不拖延,频率较快,不同于长线的价值投资,所以换股会比较频繁,这种情况下选股就比较讲究. 一.短线选股操作常用技巧 1.首选短期热点龙头股 短线操作的对象就是要选择被市场广泛关注,而大部分人还在犹豫而不敢介

.Net常用技巧_VS2005[C#] 操作 Excel 全攻略(转)

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using Microsoft.Office.Interop.Excel; using System.Data.SqlClient; using System.Data.

.Net常用技巧_操作Excel知识点

C#操作Excel知识点 近期在使用C#操作excel,主要是读取excel模板,复制其中的模板sheet页,生成多个sheet页填充相应数据后另存到excel文件,所用到的知识点如下. 一.添加引用和命名空间 添加Microsoft.Office.Interop.Excel引用,它的默认路径是C:\Program Files\Microsoft Visual Studio 9.0\Visual Studio Tools for Office\PIA\Office12\Microsoft.Off