离散化

离散化

当一个数组长度较大,数组中仅有少量元素有值

我们需要对其进行多次查询操作,查询某一区间的元素的总和是多少

此时我们可对该数组进行一系列的操作,只关心有值的元素下标和查询操作的左右区间下标

离散化就是对这些下标进行一个映射

映射

对于一个连续数组A,求区间[l, r]的元素总和,l, r为连续数组的下标,可使用前缀和,S[r] - S[l-1]

而对于一个比较稀疏的数组X,我们要求的是[L, R],由于L, R下标之间元素很稀疏,我们可将LR区间的有值元素以及LR区间的下标映射为一个连续数组,如下图所示

此时A[k] = X[f(k)'],即A[K]存取的是原数组X的值

对A进行前缀求和得到数组S,区间[L, R]的元素和即为S[K+3] - S[K]

 

注意:映射关系需要保证坐标的先后顺序不变

实现:

将数组X中有值元素的下标和需要进行查询操作的下标保存为一个数组T

为保证使用映射关系后坐标的先后顺序不变, 我们需要对数组T进行一个升序排列

因此,我们将有值元素的下标和需要进行查询操作的下标进行了一个映射,从数组X映射到了数组A,映射关系为数组T

数组T内存的是数组X的下标,而数组A存的则是X[T],即在X中下标为T[i]的值

 

每次通过二分查找数组T得到位置i,参数x为在X数组中的下标

 1 int find(int x)
 2 {
 3     int l = 0, r = T.size()-1;
 4     while(l < r)
 5     {
 6         int mid = l + r >> 1;
 7         if(T[mid] >= x) r = mid;
 8         else l = mid + 1;
 9     }
10     return r + 1;
11 }

 重复情况

若映射关系为下图所示,则返回结果错误

解决方法:

1. 去掉数组T中相同元素

2. 规定查找时返回等于被查找数的最小下标,或最大下标。不能在赋值查找与查询查找时分别返回最小和最大,或者返回最大和最小

 

posted @ 2019-07-10 21:54  roov  阅读(5)  评论(0编辑  收藏  举报