zoukankan      html  css  js  c++  java
  • 离散化处理

    什么是离散化呢?比如有这么一道题:

    题目描述
    小鱼有 n 名优秀的粉丝。

    粉丝们得知小鱼将会在一条直线上出现,打算去膜他。为了方便,粉丝们在这条直线上建立数轴。

    第 i 名粉丝有一个侦查区间[li,ri] 。如果小鱼在 j(li≤j≤ri) 处出现,这名粉丝将立刻发现并膜他。

    小鱼希望膜他的人越多越好,但是他不能分身,因此只能选择一个位置出现。

    小鱼想知道自己最多能被多少个人膜。
    输入
    第一行一个整数n —— 粉丝的个数。

    接下来 n 行,每行两个整数 li,ri ,分别表示第 i 名粉丝的侦查区间的两个端点。两个数之间用空格隔开。
    输出
    共一行,一个整数,表示小鱼最多能被多少人膜。
    样例输入

    4
    3 5
    4 8
    1 2
    5 10
    

    样例输出
    3
    提示
    样例解释:

    如图所示,小鱼可出现在5处,此时第1,2,4号粉丝可以膜他。小鱼最多只能被3个粉丝膜。
    在这里插入图片描述

    对于20%的数据,n≤2
    对于60%的数据,n≤2000
    对于100%的数据,1 ≤ n ≤ 5 × 104,1 ≤ li ≤ ri <230

    输入的数据不超过 5e4,但是后面的区间范围却很大;
    按照以前的思想,应该是进行差分处理,但是却因为数据范围太大而无法进行寻常的差分处理,这时就可以进行离散化处理;
    离散化:比如输入的有6个数 ,分别为: 1 9 100000000000 9999999999999999999 12312352346541236471263 1234
    经过离散化之后这6个数分别代表 1 2 4 5 6 3
    因此可以看出将数据从小到大进行排序,然后每个数可以换成排序之后的数组的小标,这样不会影响相互之间的大小关系,这样一来,就可以使得以前比较大的数据范围缩小了很大一部分,正适合我们的意愿,但是可能有同一个数据出现若干次的情况,这次就要进行去重处理

    比如有 六个数分别为: 1 9 9999999999999999999 9999999999999999999 123123312312352346541236471263 9999999999999999999
    那么这六个数进行离散化就变成了:
    1 2 3 3 4 3
    因此离散化一般的过程就是: 排序去重

    经常用STL里面的不定长数组,sort一遍之后,然后进行去重

    vet.erase(unique(vet.begin(),vet.end()),vet.end());
    

    erase用于删除元素,常用的用法是:

     vec.erase(vec.begin()+i,vec.end()+j);删除区间[i,j-1];区间从0开始
    

    unique的作用是“去掉”容器中相邻元素的重复元素(不一定要求数组有序),它会把重复的元素添加到容器末尾(所以数组大小并没有改变),而返回值是去重之后的尾地址,下面举个例子。
    具体的话可以看巨巨的博客
    unique函数的去重过程实际上就是不停的把后面不重复的元素移到前面来,也可以说是用不重复的元素占领重复元素的位置。处理完之后,他的返回值是一个迭代器,它指向的是去重后容器中不重复序列的最后一个元素的下一个元素。
    unique 返回的是最后一个去重完之后的元素的下一个元素,而erase的时候,正好是将从这个元素开始到end的所有重复元素进行删除
    细心的小伙伴此时可能已经发现了,运用上面的两个函数一起使用就可以达到真正的去重功能,因为erase之后直接将多余的元素进行删除了,容器的size也减小了

    而用lower_bound二分后面的操作得到的下标就正好是第几个元素,此时的下标就是每个元素对应的相对大小,也就是第几大或者是第几小

    以上的参考代码为:

    ll maxx=-1,minn=inf;
    ll num[maxn],a[maxn],num2[maxn];
    ll res,ans;
    int n;
    ll cnt[maxn];
    pair<ll,ll> together[maxn];
    vector <ll> vet;
    int main()
    {
        n=read;
        for(int i=1;i<=n;i++){
            ll left=read,right=read;
            vet.push_back(left);
            vet.push_back(right);
            together[i]={left,right};
        }
        sort(vet.begin(),vet.end());
        vet.erase(unique(vet.begin(),vet.end()),vet.end());
    
        for(int i=1;i<=n;i++){
            ll left=together[i].first;
            ll right=together[i].second;
            ll templeft=lower_bound(vet.begin(),vet.end(),left)-vet.begin();
            ll tempright=lower_bound(vet.begin(),vet.end(),right)-vet.begin();
            num[templeft]+=1;
            num[tempright+1]-=1;
        }
        int len=vet.size();
        for(int i=1;i<len;i++) num[i]+=num[i-1];
        ans=num[0];
        for(int i=1;i<len;i++) if(num[i]>=ans) ans=num[i];
        cout<<ans<<endl;
        return 0;
    }
    
  • 相关阅读:
    Android layout属性大全
    如何看懂Code128条形码
    二维码
    在线条形码生成器
    GS1已分配给国家(地区)编码组织的前缀码
    POJ 3321 Apple Tree DFS序+fenwick
    bootstrap之WaitForIdle&amp;&amp;Clear
    ubuntu14操作系统chrome标签和书签乱码解决
    动态规划-hdoj-4832-百度之星2014初赛第二场
    截取符合指数分布的一部分样本的理论与实验
  • 原文地址:https://www.cnblogs.com/PushyTao/p/14507433.html
Copyright © 2011-2022 走看看