Queries about less or equal elements
You are given two arrays of integers a and b. For each element of the second array bj you should find the number of elements in array a that are less than or equal to the value bj.
Input
The first line contains two integers n, m (1 ≤ n, m ≤ 2·10^5) — the sizes of arrays a and b.
The second line contains n integers — the elements of array a ( - 10^9 ≤ ai ≤ 10^9).
The third line contains m integers — the elements of array b ( - 10^9 ≤ bj ≤ 10^9).
Output
Print m integers, separated by spaces: the j-th of which is equal to the number of such elements in array a that are less than or equal to the value bj.
Example
Input
5 4
1 3 5 7 9
6 4 2 8
Output
3 2 1 4
Input
5 5
1 2 1 2 5
3 1 4 1 5
Output
4 2 4 2 5
题意:
给两个数组,对第二个数组中的每个元素,在第一个数组中找出小于等于它的数的个数。
思路:
暴力做肯定是不可以的,两个数组的长度都可到达
105
的数量级,暴力寻找至少需要100秒的时间。
这题有多种做法,我的方案是将数组元素离散化后用树状数组记录各个数字的出现次数,再按第二个数组查询区间和的方式解出答案的。只需注意一下,要将两个数组的的元素取并集,对这个并集进行离散化处理。
还有更简单的STL做法,即对第一个数组排序后使用upper_bound()函数,查一下第二个数组中的每个元素分别在第一个数组中处于哪个位置即可方便地知道答案了。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 2e5+19;
int n, m;
int C[maxn<<1];
int sample[maxn<<1];
int a[maxn], b[maxn];
void add(int x, int d){
while(x <= n+m){
C[x] += d; x += x&-x;
}
}
int sum(int x){
int ret = 0;
while(x){
ret += C[x]; x -= x&-x;
}
return ret;
}
int main()
{
#ifdef TEST
freopen("test.txt", "r", stdin);
#endif // TEST
while(cin >> n >> m){
memset(C, 0, sizeof(C));
for(int i = 0; i < n; i++){
scanf("%d", &a[i]);
sample[i] = a[i];
}
for(int i = 0; i < m; i++){
scanf("%d", &b[i]);
sample[n+i] = b[i];
}
sort(sample, sample+m+n);
int len = unique(sample, sample+m+n) - sample;
for(int i = 0; i < n; i++){
a[i] = lower_bound(sample, sample+len, a[i]) - sample + 1;
add(a[i], 1);
}
for(int i = 0; i < m; i++){
b[i] = lower_bound(sample, sample+len, b[i]) - sample + 1;
}
for(int i = 0; i < m; i++){
printf("%d%c", sum(b[i]), " \n"[i==m-1]);
}
}
return 0;
}