范围查询(Range)

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

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值