zoukankan      html  css  js  c++  java
  • 关于lower_bound( )和upper_bound( )的常见用法

    以下博客转载自:https://blog.csdn.net/qq_40160605/article/details/80150252

     

    lower_bound( )和upper_bound( )都是利用二分查找的方法在一个排好序的数组中进行查找的。

     

    在从小到大的排序数组中,

     

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

     

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

     

    在从大到小的排序数组中,重载lower_bound()和upper_bound()

     

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

     

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

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=100000+10;
    const int INF=2*int(1e9)+10;
    #define LL long long
    int cmd(int a,int b){
        return a>b;
    }
    int main(){
        int num[6]={1,2,4,7,15,34}; 
        sort(num,num+6);                           //按从小到大排序 
        int pos1=lower_bound(num,num+6,7)-num;    //返回数组中第一个大于或等于被查数的值 
        int pos2=upper_bound(num,num+6,7)-num;    //返回数组中第一个大于被查数的值
        cout<<pos1<<" "<<num[pos1]<<endl;
        cout<<pos2<<" "<<num[pos2]<<endl;
        sort(num,num+6,cmd);                      //按从大到小排序
        int pos3=lower_bound(num,num+6,7,greater<int>())-num;  //返回数组中第一个小于或等于被查数的值 
        int pos4=upper_bound(num,num+6,7,greater<int>())-num;  //返回数组中第一个小于被查数的值 
        cout<<pos3<<" "<<num[pos3]<<endl;
        cout<<pos4<<" "<<num[pos4]<<endl;
        return 0;    
    } 


    应用举例:
    蓝桥杯 : https://blog.csdn.net/charles_zaqdt/article/details/79786821

    标题:递增三元组

    给定三个整数数组
    A = [A1, A2, ... AN], 
    B = [B1, B2, ... BN], 
    C = [C1, C2, ... CN],
    请你统计有多少个三元组(i, j, k) 满足:
    1. 1 <= i, j, k <= N 
    2. Ai < Bj < Ck

    【输入格式】 
    第一行包含一个整数N。
    第二行包含N个整数A1, A2, ... AN。
    第三行包含N个整数B1, B2, ... BN。
    第四行包含N个整数C1, C2, ... CN。

    对于30%的数据,1 <= N <= 100 
    对于60%的数据,1 <= N <= 1000 
    对于100%的数据,1 <= N <= 100000 0 <= Ai, Bi, Ci <= 100000

    【输出格式】
    一个整数表示答案

    【样例输入】
    3
    1 1 1
    2 2 2
    3 3 3

    【样例输出】

    27

    可以先对三个数组排序,然后遍历数组b,查找a数组中有多少个小于b[i]的,c数组中有多少个大于b[i]的。


    还有就是可以直接线性求出答案,即a[x]表示第一个序列中,有多少个数字等于x,b[],c[]同理那么有:
    for i = 100000 → 0
    c[i] = c[i]+c[i+1]
    b[i] = b[i]*c[i+1]+b[i+1]
    a[i] = a[i]*b[i+1]+a[i+1]

    最后a[0]就是答案

    以下是二分方法实现代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int MAXN = 100005;
    int a[MAXN],b[MAXN],c[MAXN];
    int n,sum;
     
    int main()
    {
      scanf("%d",&n);
      for(int i=0;i<n;i++)scanf("%d",&a[i]);
      for(int i=0;i<n;i++)scanf("%d",&b[i]);
      for(int i=0;i<n;i++)scanf("%d",&c[i]);
      sort(a,a+n);
      sort(b,b+n);
      sort(c,c+n);
      sum = 0;
      for(int i=0;i<n;i++){
        int x = (lower_bound(a,a+n,b[i]) - a);
        int y = (n - (upper_bound(c,c+n,b[i]) - c));
        sum += x*y;
      }
      printf("%d
    ",sum);
      return 0;
    }

    用lower_bound( )和upper_bound( )来实现二分,可以使这个问题最大程度的简单化。

     

  • 相关阅读:
    Spring框架学习09——基于AspectJ的AOP开发
    Spring框架学习08——自动代理方式实现AOP
    Spring框架学习07——基于传统代理类的AOP实现
    Spring框架学习06——AOP底层实现原理
    Spring框架学习05——AOP相关术语详解
    SpringMVC框架09——@ResponseBody的用法详解
    Spring框架学习04——复杂类型的属性注入
    Spring框架学习03——Spring Bean 的详解
    Spring框架学习01——使用IDEA开发Spring程序
    sqlserver 迁移
  • 原文地址:https://www.cnblogs.com/myxdashuaige/p/10491341.html
Copyright © 2011-2022 走看看