离散化
一些题目的数据跨度很大,用数组按顺序来存储这些数很浪费空间,有时数组容量还不够(比如1e9),此时就需要离散化处理。改变相对数据之间的相对大小,将其一一映射到数组中。
求出一组数中某个数是第几大
比如,有一组数据
{
19
,
19
,
888
,
45
,
−
46
,
1
,
56431
,
0
,
87
,
45
,
1
19,19,888,45,-46,1,56431,0,87,45,1
19,19,888,45,−46,1,56431,0,87,45,1}
求出每一个数是第几大,可以先把他们放进一个
v
e
c
t
o
r
vector
vector,然后
v
e
c
t
o
r
vector
vector先排序,然后去重,再二分查找。
示例代码如下
#include<bits/stdc++.h>
using namespace std;
#define PII pair<int,int>
vector<int>v;
int find(int x)
{
int l=0,r=v.size();
while(l<r)
{
int mid=(l+r)>>1;
if(v[mid]>=x)
r=mid;
else
l=mid+1;
}
return l+1;
}
int main()
{
int arr[]={19,19,888,45,-46,1,56431,0,87,45,1};
for(auto x:arr)
v.push_back(x);
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());//这部是去重,必须先排序
for(auto x:arr)
printf("%d在数组内排第%d\n",x,find(x));
return 0;
}
v.erase(unique(v.begin(),v.end()),v.end());是将有序vector里面的元素去重,使用这个之前必须先排序
模板题链接:AcWing 802.区间和
对于这道题:洛谷 P1955 程序自动分析
因为数据范围很大,所以想到用离散化来做,先把每个数存入
v
e
c
t
o
r
vector
vector,然后排序再去重,再在
v
e
c
t
o
r
vector
vector里面二分查找每个数。用并查集的时候,加入要查找
999
999
999这个数,查找到他在
v
e
c
t
o
r
vector
vector的第
x
x
x个位置上,因为去了重,每个数的位置都是唯一的,我们就可以用并查集使用的数组的
f
[
x
]
f[x]
f[x]的这个下标
x
x
x这个数来代表
999
999
999这个数。