洛谷 B3694:数列离散化 ← 数组 + sort + map

【题目来源】
https://www.luogu.com.cn/problem/B3694

【题目描述】
给定一个长度为 n 的数列 a。定义 rank(i) 表示数列 a 中比 ai 小的不同数字个数再加一。
对 1≤i≤n,现在请你求出所有的 rank(i)。

【输入格式】
输入的第一行是一个整数,表示数据组数 T。接下来依次给出每组数据的信息:
第一行是一个整数,表示数列长度 n。
第二行有 n 个整数表示数列 a,第 i 个整数表示 ai。

【输出格式】
对每组数据,输出一行 n 个整数,用空格隔开,依次表示 rank(1) 到 rank(n)。​​​​​​​

【输入样例】
3
3
1 2 3
5
1 6 2 2 7
4
-1 -2 -3 -3​​​​​​​

【输出样例】
1 2 3
1 3 2 2 4
3 2 1 1​​​​​​​

【数据范围】
对全部的测试点,保证 1≤T≤5,1≤n≤10^5,−10^9≤ai≤10^9。

【算法分析】
● 离散化的本质是通过映射将连续或大范围数据转换为紧凑的整数序列,同时保持原始数据的相对大小关系‌。

● 离散化的应用场景
(1)前缀和与差分:当数据范围大但数量少时。
(2)线段树与树状数组:需要连续下标时。
(3)计数排序:处理大范围整数排序。
(4)二维离散化:处理平面坐标等二维数据。

● STL map 是一种关联容器,存储键值对,每个键(key value)是唯一的,而值(mapped value)可以重复。构建 STL map 时,无论元素插入顺序如何,STL map 中的元素始终按“键值”自动递增存储。STL map 中的迭代器可理解为“指针”。

find(x):返回一个迭代器,该迭代器指向“键 x”所在的元素。若找不到 x,返回 end() 得到的迭代器。

end():返回一个迭代器,该迭代器指向 map 最后一个元素的下一个位置。

【算法代码

#include <bits/stdc++.h>
using namespace std;

const int maxn=1e5+5;
int a[maxn],t[maxn];

int main() {
    int T,n;
    cin>>T;
    while(T--) {
        memset(a,0,sizeof a);
        map<int,int> mp;
        int id=1;
        cin>>n;
        for(int i=0; i<n; i++) {
            cin>>a[i];
            t[i]=a[i];
        }
        sort(t,t+n);

        for(int i=0; i<n; i++) {
            if(mp.find(t[i])==mp.end()) {
                mp[t[i]]=id++;
            }
        }

        for(int i=0; i<n; i++) { //输出离散化结果
            cout<<mp[a[i]]<<" ";
        }
        cout<<endl;
    }
    return 0;
}

/*
in:
3
3
1 2 3
5
1 6 2 2 7
4
-1 -2 -3 -3

out:
1 2 3
1 3 2 2 4
3 2 1 1
*/




【参考文献】
https://blog.csdn.net/hnjzsyjyj/article/details/155169602
https://blog.csdn.net/hnjzsyjyj/article/details/153268411
https://blog.csdn.net/hnjzsyjyj/article/details/143275575





posted @ 2025-11-24 14:53  Triwa  阅读(9)  评论(0)    收藏  举报