标签:size span 没有 优秀 现在 scan 两种 空间 操作
离散化,把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率
那么举个栗子,某个题目告诉你有1e5个数,每个数大小不超过1e9,要你对这些数进行操作(比如并查集之类的)。那么肯定不能直接开1e9大小的数组,但是1e5的范围就完全没问题。在举个栗子,现在对{4,7,6,9}进行离散化,那么得到的结果是{1,3,2,4},也就是说,当我们并不需要这些数据具体是多少时,就只需要知道他们的相对大小就行了。
离散化的方法有两种,一种是有重复元素的,一种是没有出现重复元素的。使用的时候务必要分清。
第一种:有重复元素的离散
1 const int maxn = 2e6+6; 2 3 int t[maxn],a[maxn]; 4 int n; 5 6 int main(){ 7 scanf("%d",&n); 8 for (int i=1;i<=n;i++){ 9 scanf("%d",&a[i]); 10 t[i] = a[i]; 11 } 12 sort(t+1,t+1+n); 13 int size = unique(t+1,t+1+n)-t-1; 14 for (int i=1;i<=n;i++){ 15 a[i] = lower_bound(t+1,t+1+size,a[i])-t; 16 } 17 for (int i=1;i<=n;i++){ 18 printf("%d ",a[i]); 19 } 20 return 0; 21 }
第二种:无重复元素的离散
这种方式的离散复杂度比第一种优秀,但是不可以处理重复的元素
1 const int maxn = 2e6+6; 2 3 struct Node{ 4 int v,id; 5 bool operator < (const Node a)const{ 6 return v < a.v; 7 } 8 }a[maxn]; 9 10 int Rank[maxn],n; 11 12 int main(){ 13 scanf("%d",&n); 14 for (int i=1;i<=n;i++){ 15 scanf("%d",&a[i].v); 16 a[i].id = i; 17 } 18 sort(a+1,a+1+n); 19 for (int i=1;i<=n;i++){ 20 Rank[a[i].id] = i; 21 } 22 for (int i=1;i<=n;i++){ 23 printf("%d ",Rank[i]); 24 } 25 return 0; 26 }
这种方法直接用结构体存储原本的数列的元素的位置,然后排序以后将他们再重新赋值。那么rank[]就是结构体a[]离散化后的结果。
举个栗子:
v: 3 6 5 10 8
id:1 2 3 4 5
排序以后:
v: 3 5 6 8 10
id:1 3 2 5 4
所以离散化以后:
v: 3 5 6 8 10
id:1 3 2 5 4
rk:1 2 3 4 5
在按原来的顺序排列:
v: 3 6 5 10 8
rk:1 3 2 5 4
标签:size span 没有 优秀 现在 scan 两种 空间 操作
原文地址:https://www.cnblogs.com/-Ackerman/p/11332893.html