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