离散化

Posted on 2022-02-22 10:11  ZheyuHarry  阅读(42)  评论(0编辑  收藏  举报

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

离散化是程序设计中一个常用的技巧,它可以有效的降低时间复杂度。其基本思想就是在众多可能的情况中,只考虑需要用的值。离散化可以改进一个低效的算法,甚至实现根本不可能实现的算法。要掌握这个思想,必须从大量的题目中理解此方法的特点。例如,在建造线段树空间不够的情况下,可以考虑离散化。

 

由于离散化这个思想是比较奇妙的算法思想,我们会用题目来帮助理解,所以这篇随笔会不定期更新!

 

e.g.1:

802. 区间和 - AcWing题库

 

题解

  首先,看到这道题,我们肯定下意识的就会想到前面讲过的一维数组求前缀和。

 然而,这道题如果简简单单的使用求前缀和,我们发现肯定会超时,因为这道题的数据是-1e9~1e9,但是我们进行插入的值最多只需要考虑到1e5个,我们可以知道,如果设置一个数组来存储,肯定会爆空间和时间。

 于是我们来看到这个数组的特点是什么,这个数组十分十分的稀疏,我们之前遇到过如果数组十分稀疏我们应该用vector不定长数组来进行记录,于是这里就要用到离散化的思路,我们不去考虑每一个数,我们把一段区间映射到一个数上,这样就成功的将1e9 >> 1e5 ,然后我们对这些数进行求前缀和,我们得到的是从-1e9到当前这个数的前缀和 。

 那么接下来,我们肯定就要去进行查询,那么这里查询就是有套路的了,我们用二分法去查找到那个小于当前数的最大值,但是紧接着我们就要去分类,因为虽然都是往左靠,对答案却有不同的影响:

我们令ll = lower_boundBS(l) ; rr = lower_boundBS(r);

·if (ll==rr) 1.l 和 r都比被操作的最小值小,直接输出0;

         2.l 比 对应ans[ll].x的值大,说明l和r是两个被操作数夹在中间的,直接输出0;

         3.l == ans[ll].x 直接输出b[rr].y  //即只有当前这个值需要被输出

·if(ll!=rr)  1.如果l <=ans[ll].x ,那么是输出ans[rr] - ans[ll] +b[ll] ;//即当前的ll要包括

          2.else则不包括b[ll] ;

The End!