10月5日备战Noip2018模拟赛7(B组)T2 Pearl 数数

版权声明:本文为博主原创文章,转载请标明出处 https://blog.csdn.net/MOMING_V/article/details/82948075

10月5日备战Noip2018模拟赛7(B组)

T2 Pearl 数数

题目描述

给定n个整数,求值在某个范围内的数的个数。

输入格式

第一行为正整数n。

第二行有n个整数(0<=数值<=231-1。)

第三行为正整数m,表示总询问次数。

以下m行,每行两个整数Ai,Bi(1<=Ai,Bi <= 2^31 - 1),表示询问值在[Ai,Bi]内的数个数(如果Ai>Bi则交换Ai,Bi)。

输出格式

输出m行,对于每次询问输出一行,表示值在[Ai,Bi]范围内的数的个数。

输入样例

7
8 2 3 5 6 7 7
6
1 5
8 6
1 10
5 5
4 4
7 8

输出样例

3
4
7
1
0
3

数据范围

对于25%的数据,有m,n<=1000。

对于100%的数据,有m,n<=100000


思路

sort + Binary searh

不过要注意有特判

二分后 l不一定小于r

扫描二维码关注公众号,回复: 3723126 查看本文章

代码

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

const int N = 100005;

int a[N];

int LowerBound (int left, int right, int x)            //寻找第一个大于等于x的数
{
	int mid;
	while (left < right){
		mid = (right - left) / 2 + left;
		if (a[mid] >= x) right = mid;
		else left = mid + 1;
	}
	return left;
}

int UpperBound (int left, int right, int x)            //寻找第一个大于x的数
{
	int mid;
	while (left < right){
		mid = (right - left) / 2 + left;
		if (a[mid] > x) right = mid;
		else left = mid + 1;
	}
	return left;
}

int main ()
{
	//freopen ("pearl.in", "r", stdin);
	//freopen ("pearl.out", "w", stdout);
	
	int n, m, l, r, ans;
	
	scanf ("%d", & n);
	for (int i = 1; i <= n; i ++){
		scanf ("%d", & a[i]);
	}
	
	sort (a + 1, a + 1 + n);            //升序排列,方便二分
	
	scanf ("%d", & m);
	for (int i = 1; i <= m; i ++){
		scanf ("%d %d", & l, & r);
		if (l > r) swap (l, r);
		if (r < a[1] || l > a[n]) ans = 0;            //所选的值不在给出的n个数内
		else {
			if (l <= a[1]) l = 1;
			else l = LowerBound (1, n, l);
			if (r >= a[n]) r = n + 1;
			else r = UpperBound (1, n, r);
			r -= 1;
			if (l > r) ans = 0;            //特判l会不会大于r
			else ans = r - l + 1;
		}

		printf ("%d\n", ans);
	
    }
	
	//fclose (stdin);
	//fclose (stdout);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/MOMING_V/article/details/82948075
今日推荐