再谈离散化

在很多情况下,问题的范围虽然定义在整数集合ZZ,但是只涉及其中mm个有限数值,并且与数值的绝对大小无关(只把这些数值作为代表,或只与它们的相对顺序有关)。此时,我们就可以把整数集合ZZ中的这mm个整数与1~m1~m建立映射关系。

通俗来讲,就是把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。

算法流程
预处理

先将无序数组排序。

去重。

二分查找

知识拓展
C++STL中的unique函数解析
C++ lower_bound 与 upper_bound 函数

模板
//离散化预处理

inline void discrete()
{
//排序
sort(a + 1,a + n + 1);
//去重
for(int i = 1;i <= n;++i)
{
if(i == 1 || a[i] != a[i-1])
//m是从0开始的 b[
++m] = a[i]; } } //二分查找 x映射为那个1~m之间的整数 inline int query(int x) { return lower_bound(b + 1,b + m + 1,x) - b; }

例题

链接

离散化+排序
这道题目是一道离散化的好题,因为我们这里的语言,是非常的分散,所以我们可以把他们汇聚在一起,也就是重新定义这些语言,重新标号1,2,3,…,n1,2,3,…,n。
这道题目统计方面,因为时间限制非常严格,所以动用了C++11的哈希级别map,和手动开O2的神仙操作吗,具体看代码吧。懒惰病发作
还要记得位运算|的运算级别是小于<<的.

注:map内部是红黑树,unordered_map内部是哈希,哈希用来查询比较方便,但是建立时间长

#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize (2)
#pragma G++ optimize (2)
#define fir(i,a,b) for (int i=a;i<=b;i++)
#define pii pair<int,int>
const int N=200100;
int n,m,sc[N],lan;
unordered_map<int,int> p,q;
pii mv[N],mv_ans[N];
int cmp(pii a,pii b)
{
    if (a.first==b.first)
        return a.second>b.second;
    return a.first>b.first;
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    fir(i,1,n)
    {
        cin>>sc[i];
        if (p[sc[i]]==0)
        {
            p[sc[i]]=(++lan);
            sc[i]=lan;
        }
        else
            sc[i]=p[sc[i]];
        q[sc[i]]++;
    }
    cin>>m;
    fir(i,1,m)
    {
        cin>>mv[i].first;
        mv[i].first=q[p[mv[i].first]];
    }
    fir(i,1,m)
    {
        cin>>mv[i].second;
        mv[i].second=q[p[mv[i].second]];
        mv_ans[i]=mv[i];
    }
    sort(mv+1,mv+1+m,cmp);
    fir(i,1,m)
        if (mv_ans[i]==mv[1])
        {
            cout<<i;
            break;
        }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/DWVictor/p/10520618.html
今日推荐