备战Noip2018模拟赛7(B组)T2 Pearl 数数

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

T2珍珠数

题目描述

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

输入格式

第一行为正整数ñ。

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

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

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

输出格式

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

输入样例

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 <= 10万


思路

排序+二进制搜索

不过要注意有特判

二分后l不一定小于r

代码

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

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值