Descriptioin
Let S be a set of n integral points on the x-axis. For each given interval [a, b], you are asked to count the points lying inside.
Input
The first line contains two integers: n (size of S) and m (the number of queries).
The second line enumerates all the n points in S.
Each of the following m lines consists of two integers a and b and defines an query interval [a, b].
Output
The number of points in S lying inside each of the m query intervals.
Example
Input
5 2
1 3 7 9 11
4 6
7 12
Output
0
3
Restrictions
0 <= n, m <= 5 * 10^5
For each query interval [a, b], it is guaranteed that a <= b.
Points in S are distinct from each other.
Coordinates of each point as well as the query interval boundaries a and b are non-negative integers not greater than 10^7.
Time: 2 sec
Memory: 256 MB
描述
数轴上有n个点,对于任一闭区间 [a, b],试计算落在其内的点数。
输入
第一行包括两个整数:点的总数n,查询的次数m。
第二行包含n个数,为各个点的坐标。
以下m行,各包含两个整数:查询区间的左、右边界a和b。
输出
对每次查询,输出落在闭区间[a, b]内点的个数。
样例
见英文题面
限制
0 ≤ n, m ≤ 5×105
对于每次查询的区间[a, b],都有a ≤ b
各点的坐标互异
各点的坐标、查询区间的边界a、b,均为不超过10^7的非负整数
时间:2 sec
内存:256 MB
思路
1.使用快速排序,先将所给数轴上的坐标进行排序
2.在数组中找lowerBound的所在数组中的下标位置:
lowerBound存在数组中,返回当前下标i
lowerBound不存在,则可找到该值在数组下标范围[i,i+1]中间,返回i+1
3.在数组中找upperBound的所在数组中的下标位置[lowerBound下标, n]:
upperBound存在数组中,返回当前下标j
upperBound不存在,则可找到该值在数组下标范围[j,j+1]中间,返回i
4.得到区间内数组个数:j - i + 1
#include <cstdio>
using namespace std;
int BinarySearch(int* NumGroup, int left, int right, int x, bool flag);
void qsort(int* NumGroup, int lo, int hi);
void swap(int* NumGroup, int i, int j);
int main()
{
#ifndef _OJ_
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
// 数组总数
int n = 0;
scanf("%d\n", &n);
// 范围数
int rangeNum = 0;
scanf("%d\n", &rangeNum);
// 数组元素填充
int* NumGroup = new int[n + 2];
NumGroup[0] = -1;
NumGroup[n + 1] = 10e7 + 1;
for (int i = 1; i < n + 1; ++i)
scanf("%d\n", &NumGroup[i]);
qsort(NumGroup, 1, n);
n = n + 2;
int** descriptioin = new int*[rangeNum];
for (int i = 0; i < rangeNum; ++i)
{
descriptioin[i] = new int[2];
scanf("%d\n", &descriptioin[i][0]);
scanf("%d\n", &descriptioin[i][1]);
}
for (int i = 0; i < rangeNum; ++i)
{
int lowerBound = BinarySearch(NumGroup, 0, n - 1, descriptioin[i][0], false);
int upperBound = BinarySearch(NumGroup, lowerBound, n - 1, descriptioin[i][1], true);
printf("%d\n", upperBound - lowerBound + 1);
}
#ifndef _OJ_
fclose(stdin);
fclose(stdout);
#endif
return 0;
}
// int flag 上界true或下届false
int BinarySearch(int* NumGroup, int left, int right, int x, bool flag)
{
int mid = (left + right + 1) / 2;
if (NumGroup[mid] == x)
return mid;
if (NumGroup[mid - 1] < x && x < NumGroup[mid])
{
if (flag)
return mid - 1;
else
return mid;
}
if (x < NumGroup[mid])
return BinarySearch(NumGroup, left, mid - 1, x, flag);
else
return BinarySearch(NumGroup, mid, right, x, flag);
}
void qsort(int* NumGroup, int lo, int hi)
{
if (lo > hi)
return;
int base = NumGroup[lo];
int i = lo;
int j = hi;
while (i != j)
{
while (NumGroup[j] >= base && i < j)
j--;
while (NumGroup[i] <= base && i < j)
i++;
swap(NumGroup, i, j);
}
swap(NumGroup, lo, i);
qsort(NumGroup, lo, i - 1);
qsort(NumGroup, i + 1, hi);
}
void swap(int* NumGroup, int i, int j)
{
int temp = NumGroup[i];
NumGroup[i] = NumGroup[j];
NumGroup[j] = temp;
}