zoukankan      html  css  js  c++  java
  • 离散化

    离散化

    蒟蒻因为即将学习主席树,发现离散化这个东东不太会,所以写一篇博客记录一下。

    概念

    离散化,就是把无限空间中有限的个体映射到有限的空间中去,以提高算法的时空效率。(来自百度百科

    作用

    ​ 很多算法的复杂度与数据中的最大值有关,比如树状数组和纯用数组实现的一对一标记。时常会遇到这种情况:数据的范围非常大或者其中含有负数,但数据本身的个数并不是很多(远小于数据范围)。在这种情况下,如果每个数据元素的具体值并不重要,重要的是他们之间的大小关系的话,我们可以先对这些数据进行离散化,使数据中的最大值尽可能小且保证所有数据都是正数。

    ​ 例如,有这样一个长为5的序列:102131511,123,9813186,-611,55。其中有非常大的数以及负数,会给许多算法的实现带来困扰,我们可以把这个序列离散化,使它变成这样:5,3,4,1,2。各个元素间的大小关系没有任何改变,但数据的范围一下子就变得很舒服了。

    代码实现

    普通离散化
    int n, a[maxn], t[maxn];
    //这里以下标1为序列的起点,一般情况下从0开始也可以
    for(int i = 1;i <= n;i++)
    {
        scanf("%d", &a[i]);
        t[i] = a[i];//t是一个临时数组,用来得到离散化的映射关系
    }
    //下面使用了STL中的sort(排序),unique(去重),lower_bound(查找)函数
    sort(t + 1, t + n + 1);//排序
    int m = unique(t + 1, t + 1 + n) - t - 1;//去重,并获得去重后的长度m
    for(int i = 1;i <= n;i++)
        a[i] = lower_bound(t + 1, t + 1 + m, a[i]) - t;//通过二分查找,快速地把元素和映射对应起来
    
    坐标离散化
    //对x1和x2进行坐标离散化,并返回离散后的宽度。(对于y1,y2同理)
    //将x1,x2更新为离散后的x1,x2.y不变在x方向上缩小。(处理y1,y2时同理)
    int compress(int *x1,int *x2,int w)
    {
        vector<int> xs;
        for(int i = 0;i < N;i++)//确定离散后x轴上哪些值还存在
        {
            for(int d = -1;d <= 1; d++)
            {
                int tx1 = x1[i] + d, tx2 = x2[i] + d;
                if(1 <= tx1 && tx1 <= w) xs.push_back(tx1);
                if(1 <= tx2 && tx2 <= W) xs.push_back(tx2);
            }
        }
        sort(xs.begin(),xs.end());
        xs.erase(unique(xs.begin(),xs.end()),xs.end());//去重
        for(int i = 0; i < N; i++)//转化为新的x1,x2;
        {
            x1[i] = find(xs.begin(),xs.end(),x1[i])-xs.begin();
            x2[i] = find(xs.begin(),xs.end(),x2[i])-xs.begin();
        }
        return xs.size();
    }
    

    放一个例题:P1955 [NOI2015]程序自动分析

    思路和代码在这里

  • 相关阅读:
    使用高精度计算斐波那契数列 c++
    纪中9日T4 2298. 异或
    洛谷 P1416 攻击火星
    线段树小结
    纪中5日T3 1566. 幸运锁(lucky.pas/c/cpp)
    Title
    Title
    Title
    Title
    Title
  • 原文地址:https://www.cnblogs.com/jasony/p/13339531.html
Copyright © 2011-2022 走看看