数轴上有n个点,对于任一闭区间 [a, b],试计算落在其内的点数。
输入
第一行包括两个整数:点的总数n,查询的次数m。
第二行包含n个数,为各个点的坐标。
以下m行,各包含两个整数:查询区间的左、右边界a和b。
输出
对每次查询,输出落在闭区间[a, b]内点的个数。
输入样例
5 2
1 3 7 9 11
4 6
7 12
输出样例
0
3
限制
0 ≤ n, m ≤ 5×105
对于次查询的区间[a, b],都有a ≤ b
各点的坐标互异
各点的坐标、查询区间的边界a、b,均为不超过10^7的非负整数
时间:2s,内存:256MB
思路
使用二分查找快速查找需要的数据,并返回下标。此二分查找返回值为不大于查找元素的最大元素的下标,故查找左边界a时,如果a恰好被找到,则最终结果需要+1,等同于left-1。
注意,输入序列不一定有序,需要先排序。
代码如下:
#include <cstdio>
#include <cstdlib>
const int SZ = 1<<20; //提升IO buff
struct fastio{
char inbuf[SZ];
char outbuf[SZ];
fastio(){
setvbuf(stdin,inbuf,_IOFBF,SZ);
setvbuf(stdout,outbuf,_IOFBF,SZ);
}
}io;
#define SIZE 500010
int vect[SIZE];
int cmp( const void *a, const void *b)
{
return *(int*)a - *(int*)b;
}
int binsearch(int lo, int hi, int *p, int e)
{
while(lo<hi)
{
int mi = (lo + hi) >> 1;
(e < p[mi])? hi = mi : lo = mi+1;
}
return --lo;
}
int main()
{
int n, m;
int i, a, b;
//freopen("in.txt", "r", stdin);
scanf("%d %d", &n, &m);
for(i = 0; i < n; i++)
{
scanf("%d", vect + i);
}
qsort( vect, n, sizeof(int), cmp);
for(i = 0; i < m; i++)
{
scanf("%d %d", &a, &b);
int left = binsearch( 0, n, vect, a);
int right = binsearch( 0, n, vect, b);
if(vect[left] == a && left >= 0) left--;
printf("%d\n", right - left);
}
return 0;
}