离散化

离散化

离散化整体分为两大部分:去重以及寻找元素在映射数组的下标。

去重

去重可以通过unique把重复元素交换至数组末尾,再用erase删除元素即可。

    sort(arr.begin(), arr.end());
    arr.erase(unique(arr.begin(), arr.end()), arr.end());

寻找

使用二分查找即可。

    auto t = lower_bound(arr.begin(), arr.end(), x);
    return distance(arr.begin(), t) + 1;

例题

AcWing 802. 区间和 (离散化模板)
题目传送门

此题是离散化+前缀和的一道模板题, 难度相对比较简单。

主要思路

离散化通过映射将数轴上一段离散稀疏的区间转化为一段连续稠密的区间,再利用前缀和即可在\(O(log \; n)\) 时间复杂度下处理查询,总的时间复杂度为\(O(m \; log \; n)\)

代码附上

#include<bits/stdc++.h>
using namespace std;
int a[300005], s[300005];
#define PI pair<int, int>
vector <int> arr;
vector <PI> add, q;
//查找
int find(int x)
{
    auto t = lower_bound(arr.begin(), arr.end(), x);
    return distance(arr.begin(), t) + 1;
}
int main()
{
    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= n; i++)
    {
        int x, c;
        cin >> x >> c;
        add.push_back({x, c});
        arr.push_back(x);
    }
    for(int i = 1; i <= m; i++)
    {
        int l, r;
        cin >> l >> r;
        q.push_back({l, r});
        arr.push_back(l);
        arr.push_back(r);
    }
    //去重
    sort(arr.begin(), arr.end());
    arr.erase(unique(arr.begin(), arr.end()), arr.end());
    for(auto it : add)
    {
        int x = find(it.first);
        a[x] += it.second;
    }
    //预处理前缀和
    for(int i = 1; i <= arr.size(); i++)
    {
        s[i] = s[i - 1] + a[i];
    }
    
    //处理查询
    for(auto it : q)
    {
        int l = find(it.first), r = find(it.second);
        cout << s[r] - s[l - 1] << '\n';
    }
    return 0;
}
posted @ 2025-11-03 13:54  ly_fish  阅读(5)  评论(0)    收藏  举报