当前位置: 代码迷 >> 综合 >> lower_bound( )和upper_bound( )的基本用法
  详细解决方案

lower_bound( )和upper_bound( )的基本用法

热度:31   发布时间:2023-11-08 13:38:10.0

lower_bound( )和upper_bound( )是C++ STL模板库中的函数,其作用可以看作是一个简单的二分模板。

基本使用方法:

lower_bound:

  1. 参数:lower_bound(首地址begin,末地址end+1,目标值);
  2. 返回值:返回在指定区域内查找大于或等于目标值的第一个元素地址;
  3. 特殊情况:在指定区域内未找到大于或等于目标值的元素则返回末地址end+1。

upper_bound:

  1. 参数:upper_bound(首地址begin,末地址end+1,目标值);
  2. 返回值:返回在指定区域内查找大于目标值的第一个元素地址;
  3. 特殊情况:在指定区域内未找到大于目标值的元素则返回末地址end+1。

适用条件:

在一有序序列中,快速查找一目标值。其时间复杂度为n*logn,可以处理1e5数量级的数据。

实例演示:

洛谷P1102

题目:A-B数对

题意:给出n个数字,从中找出符合A-B=C的数对个数。其中1≤n≤2×105,A,B在长整型范围内。

思路:

? 我们先将n个数排序。

? 我们将A-B=C变化为A=B+C,所以只需要找到数组中的某个元素等于另一个元素+C等于A的情况数。

? 对于数组中第i个元素来说,ai-1+C是一个确定的值,我们将其设置为目标值,lower_bound函数的作用是找出第一个大于等于目标值的数所在地址,upper_bound函数的作用是找出第一个大于目标值的数所在地址。由于数组的地址是连续的,所以我们将两个地址相减,就可以得到等于目标值的数的个数。即找到ai+C的个数。

? 令B为数组元素ai,令ai+C为A,找到符合情况的个数。

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5;
ll a[N];
inline ll LintRead()
{
    char ch = getchar();int s = 0, w = 1;while(ch < '0' || ch > '9'){
    if(ch == '-') w = -1;ch = getchar();}while(ch >= '0' && ch <= '9'){
    s = s * 10 + ch - '0',ch = getchar();}return s * w;
}
int main()
{
    int c,n;ll ans=0;cin>>n>>c;for(int i=0;i<n;i++)a[i]=LintRead();//快读sort(a,a+n);for(int i=0;i<n;i++)ans+=(upper_bound(a,a+n,a[i]+c)-lower_bound(a,a+n,a[i]+c));//地址连续,可以直接相减cout<<ans;
}

lower_bound和upper_bound函数在结构体中的应用

两种形式:

1.比较函数的定义:

struct stu
{
    int w,v;
}
bool com(stu x,stu y)
{
    if(x.w!=y.w)return x.w<y.w;elsereturn x.v<y.v;
}stu a;//使用方法:
lower_bound(a+1,a+1+n,com);

2.结构体的构造

struct stu{
    int w,v;bool operator < (const stu &y) const{
    if(w!=y.w)return w<y.w;elsereturn v<y.v;}
};stu a;//使用方法:
upper_bound(a+1,a+1+n);

实例演示:

codeforces 699 div2 C题

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int M=1e5+5;
typedef long long ll;
int t,a[M],b,c[M],n,m,ans[M];
struct A
{
    int x,b,index;
};
A d[M];
bool com(A xb,A yb)
{
    if(xb.x!=yb.x)return xb.x<yb.x;elsereturn xb.b<yb.b;
}
void fun(int cx)
{
    A *q;q=upper_bound(d+1,d+1+n,(A){
    cx,0,0},com);int h=upper_bound(d+1,d+1+n,(A){
    cx,0,0},com)-d;//通过地址的相对位置找到下标if((*(q-1)).x==cx){
    p.x=(*(q-1)).x;p.index=(*(q-1)).index;(*(q-1)).b=1;}else if((*q).x==cx&&h<=n)//注意判断是否超出范围{
    p.x=(*q).x;p.index=(*q).index;}
}
int main()
{
    cin>>t;while(t--){
    scanf("%d%d",&n,&m);for(int i=1; i<=n; i++)scanf("%d",&a[i]);for(int i=1; i<=n; i++){
    scanf("%d",&b);d[i].x=b;if(b==a[i])d[i].b=1;elsed[i].b=0;d[i].index=i;}sort(d+1,d+1+n);//nlognfor(int i=1; i<=m; i++)scanf("%d",&c[i]);for(int i=1; i<=m; i++){
    p.x=-1;fun(c[i]);if(p.x!=-1)ans[i]=p.index;elseans[i]=0;}for(int i=m-1; i>=1; i--){
    if(ans[i]==0)ans[i]=ans[m];}bool bb=1;for(int i=1; i<=n; i++)if(d[i].b==0)bb=0;if(!bb||ans[m]==0){
    printf("NO\n");/*for(int i=1;i<m;i++)printf("%d ",ans[i]);printf("%d\n",ans[m]);*/}else{
    printf("YES\n");for(int i=1; i<m; i++)printf("%d ",ans[i]);printf("%d\n",ans[m]);}}
}