Tsinghua MOOC 范围查询(Range)

来源:互联网 发布:dll文件恢复软件 编辑:程序博客网 时间:2024/05/22 06:05

数轴上有n个点,对于任一闭区间 [a, b],试计算落在其内的点数。

输入

第一行包括两个整数:点的总数n,查询的次数m。

第二行包含n个数,为各个点的坐标。

以下m行,各包含两个整数:查询区间的左、右边界a和b。

输出

对每次查询,输出落在闭区间[a, b]内点的个数。

输入样例

5 2
1 3 7 9 11
4 6
7 12

输出样例

03

限制

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 500010int 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;}



0 0
原创粉丝点击