信息学竞赛中离散化算法

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

什么时候使用离散化


先看一到例题

给定 n 个数(可能相同)a1,a2…an,出现次数最多的数出现了多少次。(n<= 2*10 ^ 5,0< ai <= 10 ^ 9)

  看似一道水题,只要开一个标记数组cnt记录每一个数字出现的次数即可,比如 cnt[a[i]]++。但是值得注意的是,ai可能非常大,这就导致 cnt 数组会开不下,此时,就要用到离散化。

离散化的步骤


本文中离散化的方式主要分两种:

1.使用结构体

步骤:
Ⅰ.开一个结构体数组来记录数的初始值data和在数组中的位置id。
Ⅱ.将结构体数组按初始值大小来排序,可以在结构体里面写了个运算符重载,或者写一个比较函数。
Ⅲ.将排序后的结构体数组中的初始值,依次存到一个rank数组中。

  Tip:按原数组source大小排序后,rank[i]就是原数组source中第i大的数,这样一来就将这个数和他是第几大映射起来,第 i 大的数出现一次,只需要 cnt[i]++ 就可以,而 i 一定是小于等于 n 的,数组只需要开到2 * 10 ^ 5就可以了。
  这样还会有一个问题:如何找到 i 呢 ,肯定不能通过rank[i] 来找到 i,这里使用将数据的输入顺序 和 排序后的顺序形成映射。

拿开始序言中的例子来分析:
  原数据:1,999,100000,15;处理后:1,3,4,2; 将原数据排序后是 1(第1大),15(第2大),999(第3大),100000 (第4大),所以离散化后就是 1,3,4,2 ,source[1] = 1,source[2] = 3,source[3] = 4,source[4] = 2,后一个区间的例子,大家可以自己试试。

代码:


#include <bits/stdc++.h>
using namespace std;

const int Max = 2e5+10;
struct Node{
   
    int data,id;
    bool operator < (const Node &a) const {
   
        return data < a.data;
    }
}node[Max];
int rank[Max],n,source[Max],cnt[Max];
int ans = 0
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值