离散化算法

2022/7/29 1:24:08

本文主要是介绍离散化算法,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

离散化

什么是离散化?

  • 一些数据范围比较大,但是数据的个数不多,将其数字映射成较小的下标
  • 从本质上来看离散化可以看成哈希,是一种特殊的哈希,其保证数据在哈希以后仍然保持原来的顺序

离散化的步骤

  • 排序
  • 去重(排序好了才能去重,可以用stl中的unique去重然后用erase去除)
  • 访问的时候可以通过二分查找(因为是有序的)或者另外建立unordered_map通过find快速查找

离散化的核心板子(源自https://www.acwing.com/blog/content/277/)

vector<int> alls; // 存储所有待离散化的值
sort(alls.begin(), alls.end()); // 将所有值排序
alls.erase(unique(alls.begin(), alls.end()), alls.end());   // 去掉重复元素

// 二分求出x对应的离散化的值
int find(int x) // 找到第一个大于等于x的位置
{
    int l = 0, r = alls.size() - 1;
    while (l < r)
    {
        int mid = l + r >> 1;
        if (alls[mid] >= x) r = mid;
        else l = mid + 1;
    }
    return r + 1; // 映射到1, 2, ...n
}

离散化的板子题(题目源自https://www.acwing.com/problem/content/804/)

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 3e5 + 10;
typedef pair<int, int> PII;
int sum[N];
int n, m;
PII add[N], ask[N];
unordered_map<int, int> mmap;
vector<int>vec;
vector<int>::iterator unique(vector<int>& t) {
    int j = 0;
    for (int i = 0; i < t.size(); ++i) {
        if (!i || t[i] != t[i - 1]) t[j++] = t[i];
    }
    return t.begin() + j;
}
inline int read() {
    char ch = getchar();
    int s = 0, f = 1;
    for (;ch < '0' || ch > '9';ch = getchar()) if (ch = '-')f = -1;
    for (;ch >= '0' && ch <= '9';ch = getchar()) s = (s << 3) + (s << 1) + (ch ^ 48);
    return f == -1 ? -s : s;
}
signed main(void) {
    n = read(), m = read();
    for (int i = 1; i <= n;++i) {
        int x, c;
        x = read(), c = read();
        add[i] = make_pair(x, c);
        vec.push_back(x);
    }
    for (int i = 1; i <= m; ++i) {
        int l, r;
        l = read(), r = read();
        ask[i] = make_pair(l, r);
        vec.push_back(l), vec.push_back(r);
    }
    sort(vec.begin(), vec.end());
    //vec.erase(unique(vec.begin(), vec.end()), vec.end());  STL中的unique
    vec.erase(unique(vec), vec.end());
    for (int i = 0; i < vec.size(); ++i) mmap[vec[i]] = i + 1;
    for (int i = 1; i <= n; ++i) {
        int idx = mmap[add[i].first];
        sum[idx] += add[i].second;
    }

    for (int i = 1; i <= vec.size(); i++) {
        sum[i] += sum[i - 1];
    }
    for (int i = 1; i <= m; ++i) {
        int ll = mmap[ask[i].first], rr = mmap[ask[i].second];
        cout << sum[rr] - sum[ll - 1] << endl;
    }
}


这篇关于离散化算法的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程