转:http://blog.csdn.net/gokou_ruri/article/details/7723378
方法一:
9 1 0 5 4 与 5 2 1 4 3 的逆序对个数相同。
设有4个数:
1234567、123456789、12345678、123456
排序:123456<1234567<12345678<123456789
=> 1 < 2 < 3 < 4
那么这4个数可以表示成:2、4、3、1
sort(sub_a,sub_a+n);
int size=unique(sub_a,sub_a+n)-sub_a;//size为离散化后元素个数
for(i=0;i<n;i++)
a[i]=lower_bound(sub_a,sub_a+size,a[i])-sub_a + 1;//k为b[i]经离散化后对应的值
对于第3步,若离散化后序列为0, 1, 2, ..., size - 1则用lower_bound,从1, 2, 3, ..., size则用upper_bound,其中lower_bound返回第1个不小于b[i]的值的指针,而upper_bound返回第1个大于b[i] 的值的指针,当然在这个题中也可以用lower_bound然后再加1得到与upper_bound相同结果,两者都是针对以排好序列。使用STL离散化 大大减少了代码量且结构相当清晰。
方法二:
转:http://m.blog.csdn.net/blog/fobdddf/21404683
假如有m个数(m较小),但是每个数的取值范围很大(0<=ai<=1000000000)。我想记录哪些数字出现过,应该怎么离散呢?我知 道最基本的作法是开一个标记的数组,哪个数字出现,就让那个数字对应的下标数组变成1,但是范围太大,没可能开1000000000的数组来存放标记,那 要怎么办?这里就应该是用STL中的map。把ai当成key,value随便都行,那么查询是否有这个数的时候使用map的函数count(key)就 可以了。
#include <iostream> #include <map> #include <vector> using namespace std; map <int,int> _map; int n,m; int main() { while(cin >> n >> m) { int temp,a,b; _map.clear(); for(int i = 1;i <= n;i++) { cin >> temp; _map[temp] = 1;//随便给一个值就行 } for(int i = 1;i <= m;i++) { cin >> b; if(!_map.count(b)) cout << 0 << endl; else cout << _map[b] << endl; } } return 0; }