在很多情况下,问题的范围虽然定义在整数集合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; }
例题
扫描二维码关注公众号,回复:
5512728 查看本文章
离散化+排序
这道题目是一道离散化的好题,因为我们这里的语言,是非常的分散,所以我们可以把他们汇聚在一起,也就是重新定义这些语言,重新标号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; }