lower_bound( )和upper_bound( )

泄露秘密 提交于 2020-02-27 13:33:14

lower_bound( )和upper_bound( )适用于有序序列,因为内部是用的二分查找,所以必须得是有序的。
它第一个参数与第二个参数是与sort一样的,也是用来确定区间范围的(闭区间)
参数:
first
寻址要搜索的范围中的第一个元素的位置的向前迭代器。
last
寻址要搜索的范围中最后一个元素的下一位置的向前迭代器。
value
在排序范围中搜索的处于第一个位置或可能处于第一个位置的值。
cmp
用户定义的谓词函数对象定义一个元素小于另一个。二进制谓词采用两个参数,并且在满足时返回 true,在未满足时返回 false。
返回值:
向前迭代器在有序的范围内(具有大于或等于指定值的值)的第一个元素的位置,其中等效性由二进制谓词指定。
在升序的数组中

lower_bound( begin,end,num):二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

upper_bound( begin,end,num):二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

在降序的数组中,我们使用第四个参数greater,重载lower_bound()和upper_bound()

lower_bound( begin,end,num,greater() ):二分查找第一个小于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

upper_bound( begin,end,num,greater() ):二分查找第一个小于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

这个东西用来查找是非常快的,再加上快读更快
以这个题目为例:https://www.luogu.com.cn/problem/P2249
我们正常写法会ETL的,只能二分答案了(倍增也可以),比赛时很明显没时间写那么多的,我们用lower_bound()一个函数就完事了

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e6+10;
int read(){
    int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-') f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        x=x*10+c-'0';
        c=getchar();
    }
    return x*f;
}
int a[MAXN];
int main(){
    int n=read(),m=read();
    for(int i=1;i<=n;i++) a[i]=read();
    while(m--){
        int x=read();
        int ans=lower_bound(a+1,a+n+1,x)-a;//这里的a代表数组a的首地址
        if(x!=a[ans]) printf("-1 ");
        else printf("%d ",ans);
    }
    return 0;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!