离散化
理解:离散化是在不改变数据相对大小的条件下,对数据进行相应的缩小。
作用:把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。
举例:
题意:有n个人(n<=105),第i个人的编号为ai(ai<=1018),m个关系表示a和b是朋友(关系可以传染),请判断是否所有人都互相认识。
此处如果按正常的并查集算法,数组需要扩到1018,但是用离散化可以使数组缩小到105。
eg: 4 2
2 34 35 23456677899
2 34 2 35
{2,34,35,23456677899}-》{1,2,3,4}
算法原理:
1.排序 sort() O(n*logn)
2.去重 O(n)
3.索引 lower_bound() n*O(logn)
扩展:
在去重步骤中,有些大佬用的是unique(),也非常方便,这里了解一下:
去重函数:unique() ----- 存在于STL中,所以头文件 ~ ~
作用:去除相邻的重复的元素,(并不是真的去除,只是将重复的元素移到数组后面了,unique返回的是去重的元素的最后一个的地址(重复元素的第一个?))
需要注意:unique去除相邻重复元素,所以用之前需要先排下序;
该函数用在字符串中,配上删除函数食用效果更佳。
效果:
1 int a[1000]; 2 int main(){ 3 int n; 4 while(~scanf("%d",&n)){ 5 for(int i=1;i<=n;i++) 6 scanf("%d",&a[i]); 7 sort(a+1,a+1+n); 8 int ans=unique(a+1,a+1+n)-a-1; 9 printf("%d\n",ans); 10 for(int i=1;i<=n;i++) 11 printf("%d ",a[i]); 12 } 13 } 14 /* 8 15 1 1 1 2 23 24 24 25 16 5 17 1 2 23 24 25 24 24 25 */
模板:
1 #include<bits/stdc++.h> 2 ll a[1000],an[1000],p[1000]; 3 int main(){ 4 int n; 5 while(~scanf("%d",&n)){ 6 int cnt=0; 7 for(int i=1;i<=n;i++){ 8 scanf("%lld",&a[i]); 9 p[i]=a[i]; 10 } 11 sort(p+1,p+1+n); 12 for(int i=1;i<=n;i++) 13 if(cnt==0||p[i]!=p[cnt]) 14 p[++cnt]=p[i]; 15 for(int i=1;i<=n;i++) 16 an[i]=lower_bound(p+1,p+1+cnt,a[i])-p; 17 //二分查找 log2(n) 18 } 19 }

浙公网安备 33010602011771号