离散化

理解:离散化是在不改变数据相对大小的条件下,对数据进行相应的缩小。

作用:把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。

举例:

      题意:有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 */
View Code

 

 

模板:

 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 }
View Code

 备注:感谢大佬

posted @ 2020-10-09 21:42  十分的月亮  阅读(218)  评论(0)    收藏  举报