lower_bound( )与upper_bound( )用法以及例题(洛谷P1102 A-B 数对)

lower_bound( )与upper_bound( )都是需要在已经排好序的数列中进行操作的

lower_bound( ): lower_bound( begin,end,num)的意思就是从数组中的头到末尾进行二分的查找,返回第一个大于等于num的数的地址,如果不存在就返回end。因此,我们就可以用返回的值减去数组的首地址 就能得到目标数的下标。

upper_bound()与lower_bound()功能类似,只不过它是返回第一个大于num值的数地址,同样我们也可以减去首地址获得下标。

重载:在一个由大到小排列的数组中 可以进行重载运算

lower_bound( begin,end,num,greater<type>() )返回的是第一个小于等于num值的数的地址

同样upper_bound( begin,end,num,greater<type>() ):返回的是第一个小于num值的数的地址

基于上述 看一下例题:

题目描述

出题是一件痛苦的事情!

相同的题目看多了也会有审美疲劳,于是我舍弃了大家所熟悉的 A+B Problem,改用 A-B 了哈哈!

好吧,题目是这样的:给出一串数以及一个数字 CC,要求计算出所有 A - B = CA−B=C 的数对的个数(不同位置的数字一样的数对算不同的数对)。

输入格式

输入共两行。

第一行,两个整数 N, CN,C。

第二行,NN 个整数,作为要求处理的那串数。

输出格式

一行,表示该串数中包含的满足 A - B = CA−B=C 的数对的个数。

输入输出样例

输入 #1复制

4 1
1 1 2 3

输出 #1复制

3

说明/提示

对于 75\%75% 的数据,1 \leq N \leq 20001≤N≤2000。

对于 100\%100% 的数据,1 \leq N \leq 2 \times 10^51≤N≤2×105。

保证所有输入数据绝对值小于 2^{30}230。

思路:

首先从小到大进行重新排序然后从头遍历,对于每一个数要找到数组中比它的值大c的数的个数

利用upper_bound()找到第一个比a[i]+c大的数字的下标,用lower_bound()找到第一个a[i]+c大的下标(因为目标数可能不止一个),两者相减就是目标数的个数。

例如c=3,a[i]=1

11223334 得到的式子就是8(4的下标)-5(第一个数值为3的下标)

for(int i=1;i<=n;i++)
	{
		f=(upper_bound(a+1,a+1+n,a[i]+c)-a)-(lower_bound(a+1,a+1+n,a[i]+c)-a);
		sum+=f;
	}

AC代码:

#include<iostream>
#include<stdlib.h>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e6+5;
ll a[200005];
long long int n,m,b,f,c,sum=0;
int main()
{
	ios::sync_with_stdio(0);	//输入输出更快 
	cin>>n>>c;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	sort(a+1,a+n+1);
	for(int i=1;i<=n;i++)
	{
		f=(upper_bound(a+1,a+1+n,a[i]+c)-a)-(lower_bound(a+1,a+1+n,a[i]+c)-a);
		sum+=f;
	}
	cout<<sum;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值