离散化,把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。
离散化是程序设计中一个常用的技巧,它可以有效的降低时间复杂度。其基本思想就是在众多可能的情况中,只考虑需要用的值。离散化可以改进一个低效的算法,甚至实现根本不可能实现的算法。要掌握这个思想,必须从大量的题目中理解此方法的特点。例如,在建造线段树空间不够的情况下,可以考虑离散化。
由于离散化这个思想是比较奇妙的算法思想,我们会用题目来帮助理解,所以这篇随笔会不定期更新!
e.g.1:
题解:
首先,看到这道题,我们肯定下意识的就会想到前面讲过的一维数组求前缀和。
然而,这道题如果简简单单的使用求前缀和,我们发现肯定会超时,因为这道题的数据是-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!