描述
数轴上有n个点,对于任一闭区间 [a, b],试计算落在其内的点数。
输入
第一行包括两个整数:点的总数n,查询的次数m。
第二行包含n个数,为各个点的坐标。
以下m行,各包含两个整数:查询区间的左、右边界a和b。
输出
对每次查询,输出落在闭区间[a, b]内点的个数。
样例
Input
5 2
1 3 7 9 11
4 6
7 12
Output
0
3
限制
0 ≤ n, m ≤ 5×105
对于每次查询的区间[a, b],都有a ≤ b
各点的坐标互异
各点的坐标、查询区间的边界a、b,均为不超过10^7的非负整数
时间:2 sec
内存:256 MB
解题思路:
很容易想到对所有点进行排序,然后通过二分查找,找到对应范围的下标,进而相减即为范围内点数。
#include <cstdio>
#include <cstdlib>
int room[500010];
//不存在则返回小于该值的最后一个元素的pos(包含哨兵[lo-1])
int mybinsearch(int v[], int const& e, int lo, int hi) {
while (lo < hi) {
int mi = (lo + hi) >> 1;
(e < v[mi]) ? hi = mi : lo = mi + 1;
}
return --lo;//返回所搜索值的前一个pos
}
int cmp(const void *a, const void *b)
{
return *(int*)a - *(int*)b;
}
int mymax(int a, int b)
{
return (a > b ? a : b);
}
int main()
{
int N, M;
scanf("%d %d", &N, &M);
for (int i = 0; i < N; ++i)
{
scanf("%d", &room[i]);
}
qsort(room,N, sizeof(int), cmp);
int start, end;
for (auto i = 0; i < M; ++i)
{
scanf("%d %d", &start, &end);
int s = mybinsearch(room, start, 0, N);
int e = mybinsearch(room, end, mymax(s,0), N);
if (s >= 0 && room[s] == start)
s--;
printf("%d\n", e - s);
}
return 0;
}
代码对应结果如下:
| Case No. | Result | Time(ms) | Memory(KB) |
|---|---|---|---|
| 1 | Accepted | 0 | 6456 |
| 2 | Accepted | 0 | 6456 |
| 3 | Accepted | 0 | 6456 |
| 4 | Accepted | 0 | 6456 |
| 5 | Accepted | 0 | 6456 |
| 6 | Accepted | 0 | 6456 |
| 7 | Accepted | 0 | 6456 |
| 8 | Accepted | 0 | 6456 |
| 9 | Accepted | 0 | 6456 |
| 10 | Accepted | 0 | 6456 |
| 11 | Accepted | 0 | 6456 |
| 12 | Accepted | 36 | 6692 |
| 13 | Accepted | 48 | 6772 |
| 14 | Accepted | 20 | 6772 |
| 15 | Accepted | 60 | 6848 |
| 16 | Accepted | 72 | 7044 |
| 17 | Accepted | 116 | 7160 |
| 18 | Accepted | 132 | 7240 |
| 19 | Accepted | 208 | 8412 |
| 20 | Accepted | 360 | 8412 |
这里列出当前Top10的结果
| Score | Worst Case | Time(ms) | Memory(KB) | |
|---|---|---|---|---|
| suzq** | 100.0 | 20 |
68 |
22580 |
| zhong3** | 100.0 | 20 |
72 |
44484 |
| hhyl** | 100.0 | 20 |
108 |
66428 |
| [Anonymous] | 100.0 | 20 |
116 |
53076 |
| hongyuan_de** | 100.0 | 20 |
124 |
30984 |
| wunschunre** | 100.0 | 20 |
132 |
53332 |
| 3830670** | 100.0 | 20 |
136 |
53048 |
| li-ch** | 100.0 | 20 |
140 |
84308 |
| 4505632** | 100.0 | 20 |
144 |
66608 |
| gwy** | 100.0 | 20 |
148 |
52524 |
可以看到相差较大,那么进行优化。

博客探讨了在数轴上处理范围查询的问题,描述了如何通过排序和二分查找来计算给定区间内的点数。给出了样例输入输出及性能限制,并指出原始方法与优化方法之间的效率差异。
&spm=1001.2101.3001.5002&articleId=106746460&d=1&t=3&u=c315cc7d747a412481dff4aeb139a81b)
2165

被折叠的 条评论
为什么被折叠?



