离散化模型

离散化算法常用来解决负值问题和取值范围过大问题。

 

模板:

使用lower_bound或者库函数set,map来写

写法1.lower_bound速度快

// 把要进行离散化的值排序去重后放入alls数组中,用二分进行映射。
int
find(int x) { return lower_bound(alls.begin(), alls.end(),x) - alls.begin() + 1; }

 

set<int> st;
unordered_map<int, int> mp;

// 使用set来进行排序去重 vector
<int> alls(st.begin(), st.end()); for(int i = 0; i < alls.size(); i ++ ) mp[alls[i]] = i + 1;

 

 

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#include<unordered_map>

using namespace std;

typedef pair<int, int> PII;

const int N = 3e5 + 10;

int n, m;
set<int> st;
unordered_map<int, int> mp;
vector<PII> add, q;
int a[N], s[N];

int main() {
    cin >> n >> m;
    
    for(int i = 0; i < n; i ++ ) {
        int x, c;
        cin >> x >> c;
        st.insert(x);
        add.push_back({x, c});
    }
    
    for(int i = 0; i < m; i ++ ) {
        int l, r;
        cin >> l >> r;
        st.insert(l);
        st.insert(r);
        q.push_back({l, r});
    }
    
    vector<int> alls(st.begin(), st.end());
    for(int i = 0; i < alls.size(); i ++ ) mp[alls[i]] = i + 1;
    
    for(auto &i : add) {
        int pos = mp[i.first];
        a[pos] += i.second;
    }
    
    for(int i = 1; i <= alls.size(); i ++ ) {
        s[i] = s[i - 1] + a[i];
    }
    
    for(auto &i : q) {
        int l = mp[i.first], r = mp[i.second];
        cout << s[r] - s[l - 1] << endl;
    }
    
    return 0;
}

 

树状数组 + 离散化

 

class Solution {
public:
    int n;
    vector<int> tr = vector<int>(100005, 0);

    int lowbit(int x) {
        return x & -x;
    }

    void update(int x) {
        for(int i = x; i <= n; i += lowbit(i)) {
            tr[i] += 1;
        }
    }

    int query(int u) {
        int res = 0;
        for(int i = u; i > 0; i -= lowbit(i)) {
            res += tr[i];
        }
        return res;
    }
    
    vector<int> countSmaller(vector<int>& nums) {
        n = nums.size();
        vector<int> res(n, 0);
        if(n == 0) return {};

        set<int> st;
        for(auto num: nums) st.insert(num);
        unordered_map<int, int> mp;
        int idx = 1;
        for(auto it: st) mp[it] = idx ++ ;

        for(int i = n - 1; i >= 0; i -- ) {
            res[i] = query(mp[nums[i]]);
            update(mp[nums[i]] + 1);
        }

        return res;
    }
};

 

posted @ 2023-11-19 10:01  深渊之巅  阅读(26)  评论(0编辑  收藏  举报