离散化
数值很大很稀疏、但个数不多时,把它们"换号"成 1,2,3…的小排名 —— 桶/数组就开得下了。
一、互动演示:大数 → 排名
原数据有上亿的大数(开不了桶)。三步:① 复制排序 → ② 去重 → ③ 每个数换成它的排名。点“下一步”。
① 原数组 a
② 排序+去重后的 b(值→排名 的对照)
③ 离散化后的 a(每个数变成排名)
点“下一步”:先把 a 复制并排序。
二、核心代码(背诵版)
vector<int> b;
for (int i = 1; i <= n; i++) b.push_back(a[i]); // 1.复制
sort(b.begin(), b.end()); // 2.排序
b.erase(unique(b.begin(), b.end()), b.end()); // 3.去重
for (int i = 1; i <= n; i++) // 4.换成排名
a[i] = lower_bound(b.begin(), b.end(), a[i]) - b.begin() + 1;
离散化保留了大小关系(排名单调),所以排序、求第 k 大、配合树状数组/线段树都不受影响。