离散化的思想和它的两种代码与区别

Posted lxy050129

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了离散化的思想和它的两种代码与区别相关的知识,希望对你有一定的参考价值。

离散化的思想和它的两种代码与区别

版权声明:觉得好的话就给他人分享一下吧,欢迎转载,码字不容易啊,转载麻烦注明出处 https://blog.csdn.net/xiangAccepted/article/details/73276826

离散化是什么:一些数字,他们的范围很大(0-1e9),但是个数不算多(1-1e5),并且这些数本身的数字大小不重要,重要的是这些数字之间的相对大小(比如说某个数字是这些数字中的第几小,而与这个数字本身大小没有关系,要的是相对大小)(6 8 9 4 离散化后即为 2 3 4 1)(要理解相对大小的意思)(6在这4个数字中排第二小,那么就把6离散化成2,与数字6本身没有关系, 8,9,4亦是如此)(2018.3.26 对这篇博客进行补充修改,被一道题的离散化卡到了,花了一晚上时间,才找到BUG(需离散化的数字有无相同的数字),黑体字为今晚对此篇博客进行了补充完善与区别)

离散化思想:因为数字太大,导致没有办法开那么大的数组,又因为数字个数并不多,这时候就可以对它们进行离散化,离散化是改变了数字的相对大小,例如,有500000个数字,他们的范围是0-1e9的,这样就满足离散化的条件。

就比如说,你可以开一个5e5的数组,但是你不能开一个1e9的数组。只改变这些数字的相对大小

 

第一种离散化

(包含重复元素,并且相同元素离散化后也要相同,推荐使用)
离散化以前一直搞不懂是怎么实现的,看了一个代码才明白。

  1.  
    const int maxn=1e5+10;
  2.  
    int a[maxn], t[maxn], b[maxn];
  3.  
    int n;
  4.  
    scanf("%d",&n);
  5.  
    for(int i=1; i<=n; i++)
  6.  
        scanf("%d",a[i]),t[i]=a[i];
  7.  
    sort(t+1,t+n+1);
  8.  
    m=unique(t+1,t+1+n)-t-1;//求出的m为不重复的元素的个数
  9.  
    for(int i=1; i<=n; i++)
  10.  
        b[i]=lower_bound(t+1,t+1+m,a[i])-t;
  11.  
    //a[i]为原来的数组,b[i]为离散化后的数组

 

原来的a[i]离散化后成了后来的a[i];

 

离散化后的a[i]范围是(1-m);
举个栗子:
原序列:6 9 4 6 4
排序后:4 4 6 6 9
unique(元素去掉重复的)后:4 6 9 6 9  ( 感谢薇亚040214同学提出疑问,为什么unique去重后是4,6,9,6,9,而不是4,6,9,4,9,大家运行下面的代码即可,2018.7.21更)

SiriusNEO大佬的解答:unique去重完后面的元素是不变的,所以是4 6 9 6 9,具体可以看C++ Reference的源码
http://www.cplusplus.com/reference/algorithm/unique/?kw=unique   2018.8.6更)

  1.  
    #include <cstdio>
  2.  
    #include <algorithm>
  3.  
    using namespace std;
  4.  
    int a[10]={6,9,4,6,4};
  5.  
    int main()
  6.  
    {
  7.  
    int n=5;
  8.  
    sort(a,a+n);//排序后4 4 6 6 9
  9.  
    n=unique(a,a+n)-a;
  10.  
    for(int i=0;i<5;i++)
  11.  
    printf("%d ",a[i]);
  12.  
    printf(" ");
  13.  
    //最后输出4 6 9 6 9
  14.  
    //SiriusNEO大佬的解答:unique去重完后面的元素是不变的,所以是4 6 9 6 9,具体可以看C++ Reference的源码
  15.  
    }


unique有一个返回值,例如有十个有序的数列3 3 5 5 6 6 6 7 7 8,不重复的数字有五个,使用unique去重之后数列变成了3 5 6 7 8 6 6 7 7 8,它只改变了前五个数字后边的不变,返回值是 最后一个改变的数字的地址。so:m=unique(t+1,t+1+n)-t-1;一般要减去首地址(t+1),m为不重复的数字的个数








以上是关于离散化的思想和它的两种代码与区别的主要内容,如果未能解决你的问题,请参考以下文章

离散化的认识

二位平面坐标的离散化

ACM入门之离散化

CCPC河南省赛-C|树状数组dfs序上处理子树问题 + 离散化

最近等对 (uniquelower_bound离散化的配合)

离散化总结