Psim【算法模板】离散化处理

离散化处理是将连续的数值离散化为一定数量的区间,常见的应用场景是处理区间询问问题。以下是一个简单的离散化处理算法模板:


#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 100005;
int n, m, a[maxn], b[maxn], c[maxn];
int lowbit(int x) {
    
    
    return x & (-x);
}
void add(int x, int k) {
    
    
    while (x <= n) {
    
    
        c[x] += k;
        x += lowbit(x);
    }
}
int sum(int x) {
    
    
    int ans = 0;
    while (x > 0) {
    
    
        ans += c[x];
        x -= lowbit(x);
    }
    return ans;
}
int main() {
    
    
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) {
    
    
        scanf("%d", &a[i]);
        b[i] = a[i];
    }
    sort(b + 1, b + n + 1);
    int cnt = unique(b + 1, b + n + 1) - b - 1;
    for (int i = 1; i <= n; i++) {
    
    
        int x = lower_bound(b + 1, b + cnt + 1, a[i]) - b;
        add(x, 1);
    }
    while (m--) {
    
    
        int l, r, k;
        scanf("%d%d%d", &l, &r, &k);
        int L = 1, R = cnt;
        while (L < R) {
    
    
            int mid = (L + R) >> 1;
            if (sum(mid) >= k) R = mid;
            else L = mid + 1;
        }
        printf("%d\n", b[L]);
    }
    return 0;
}

具体做法如下:

将所有数值存入数组 b 中,对 b 数组进行排序并去重,记录去重后的数字个数 cnt。

对原数组中的每个数值求其在去重后的数组 b 中的下标 x,然后使用树状数组记录下标出现的次数。

对于每个查询区间 [l, r],二分区间中第 k 小的元素,然后根据元素在 b 数组中的下标,输出区间内第 k 小的数值。

猜你喜欢

转载自blog.csdn.net/AQRSXIAO/article/details/132089748