Tsinghua MOOC 范围查询(Range)

数轴上有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;
}



  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值