首页 > 编程语言 >C++ lower_bound 函数用法

C++ lower_bound 函数用法

时间:2024-11-11 21:47:05浏览次数:4  
标签:__ lower bound C++ len half first

C++ lower_bound 函数用法

因为文本块不支持下划线,所以以下均打成 \(\text{lower-bound}\)。

虽然只是简单语法,但是我确实不太能记住。比如很多分块题要求在整块二分,此时如果能善用 \(\text{lower-bound}\) 函数就能少写一个二分。

然后本文只是作者自己看源代码理解的,当然是有不准确的地方。并且本文只会从算法竞赛的角度分析,如果你是程序员那建议不要看。


\(\text{lower-bound}\) 的平凡用法是在整数序列中找第一个大于 \(x\) 的位置,其中要求原序列必须有序。比如以下代码:

int a[5] = {1, 3, 4, 6, 7};
int que[5] = {0, 2, 3, 6, 8};
for (int i = 0; i < 5; ++i) {
  int x = que[i];
  auto it = lower_bound(a, a + 5, x);
  cout << it - x << ' '; 
}
cout << '\n';

输出为

0 1 2 3 5

注意 \(\text{lower-bound}\) 返回的是迭代器,如果要输出值的话可以用 *it。但是上面的代码改成输出 *it 会有问题,因为 it 在最后一次询问中会变成 a + 5,没注意的话可能就会 \(\text{RE}\),这也是写代码时需要注意的地方。


但是如果真的这么简单的话,我也就不需要专门用一篇博客记录了。当然,\(\text{lower-bound}\) 还有更加高级的用法,你可以使用一个 lower_bound(b, e, x, cmp) 在找 be 中第一个不满足 cmp(a, x) 的元素 a 的位置,其中 cmp 可以是你自己定义的一个比较器。源代码为

template<typename _ForwardIterator, typename _Tp, typename _Compare>
    _ForwardIterator
    __lower_bound(_ForwardIterator __first, _ForwardIterator __last,
		  const _Tp& __val, _Compare __comp)
    {
      typedef typename iterator_traits<_ForwardIterator>::difference_type
	_DistanceType;

      _DistanceType __len = std::distance(__first, __last);

      while (__len > 0)
	{
	  _DistanceType __half = __len >> 1;
	  _ForwardIterator __middle = __first;
	  std::advance(__middle, __half);
	  if (__comp(__middle, __val))
	    {
	      __first = __middle;
	      ++__first;
	      __len = __len - __half - 1;
	    }
	  else
	    __len = __half;
	}
      return __first;
    }

同理,upper_bound(b, e, x, cmp) 可以找到 be 中第一个满足 cmp(x, a) 的元素 a 的位置,其中 cmp 当然也可以自定义。源代码为:

template<typename _ForwardIterator, typename _Tp, typename _Compare>
    _ForwardIterator
    __upper_bound(_ForwardIterator __first, _ForwardIterator __last,
		  const _Tp& __val, _Compare __comp)
    {
      typedef typename iterator_traits<_ForwardIterator>::difference_type
	_DistanceType;

      _DistanceType __len = std::distance(__first, __last);

      while (__len > 0)
	{
	  _DistanceType __half = __len >> 1;
	  _ForwardIterator __middle = __first;
	  std::advance(__middle, __half);
	  if (__comp(__val, __middle))
	    __len = __half;
	  else
	    {
	      __first = __middle;
	      ++__first;
	      __len = __len - __half - 1;
	    }
	}
      return __first;
    }

这样的话很多题的代码其实可以简单很多,因为可以重载 cmp 的话其实拓展空间挺大的。

标签:__,lower,bound,C++,len,half,first
From: https://www.cnblogs.com/estruct/p/18540653

相关文章

  • C向C++过渡篇(一)
    ----------bool类型:c++独有,这是一种数据类型,用来描述“真”或“假“用sizeof(bool)来求bool类型变量在内存中占多少个字节的内存,得出,bool类型在内存中占用一个字节取值范围:只有两个值:turn(真的),false(假的)bool,可以给它赋值别的值,遵循“非0为真”原则----------内联函数......
  • C++【深入项目-检测键盘】
    神马是检测键盘,就是让编辑器可以检测键盘按下了什么按键,我们先科普复习检测键盘 。检测键盘需要用到一些函数,请见下:!KEY_DOWN(80)这个代码是检测按下键盘上P按键。那80是什么?原来是对应按键的,不只有数字表示,还有字母表示:说明BackSpaceBackSpace8TabTab9Clear12En......
  • c++ 对于传递引用和传递值的理解
    首先先上一段c++代码,可以看出foo函数参数是引用类型,bar函数参数是值类型typedefstructA{intx;inty;}A;voidfoo(A&a){ra.x++;}voidbar(Aa){a.x++;}intmain(){Aa={1,2};foo(a);bar(a);return0;}在vscode......
  • 深入计算机语言之C++:STL之string的认识与使用
    ......
  • 【C++】踏上C++的学习之旅(七):深入“类和对象“世界,掌握编程的黄金法则(二)(内含构造函数
    文章目录前言1.类的6个默认的成员函数2.构造函数和析构函数的“好处”3.构造函数3.1概念3.2构造函数的特性4.析构函数4.1概念4.2特征前言在踏上C++的学习之旅(六):深入“类和对象“世界,掌握编程的黄金法则(一)中,我给大家讲解了"类"的定义以及如何使用类创建出......
  • 2024年华为OD机试真题-光伏场地建设规划 -C++-OD统一考试(E卷)
    最新华为OD机试考点合集:华为OD机试2024年真题题库(E卷+D卷+C卷)_华为od机试题库-CSDN博客     每一题都含有详细的解题思路和代码注释,精编c++、JAVA、Python三种语言解法。帮助每一位考生轻松、高效刷题。订阅后永久可看,发现新题及时跟新。题目描述祖国西北部有一片大片......
  • C++ 核心代码
    C++核心代码通常指一些基础、常用的代码片段,可以用于各种C++项目中,包括输入输出、基本数据结构、算法实现等。下面是一些典型的C++核心代码示例:1.基本输入输出cppinclude<iostream>usingnamespacestd;intmain(){inta,b;cout<<"Entertwonumbe......
  • 解决 VSCode 中 C/C++ 编码乱码问题的两种方法
    解决VSCode中C/C++编码乱码问题的两种方法在中国地区,Windows系统中的cmd和PowerShell默认编码是GBK,但VSCode默认使用UTF-8编码。这种编码不一致会导致在VSCode终端中运行C/C++程序时出现乱码。以下介绍两种方法来解决这一问题。方法一:通过CodeRunner......
  • C++数学
    前言C++算法与数据结构打开打包代码的方法兼述单元测试数论:质数、最大公约数、菲蜀定理组合数学汇总计算几何博弈论曼哈顿距离与切比雪夫距离红线是哈曼顿距离,绿线是切比雪夫距离。二维曼哈顿距离转切比雪夫距离曼哈顿距离:|x1-x2|+|y1-y2|。典型应用:某个棋子只能......
  • C++ 的“活动范围”:变量的作用域和生命周期,一次搞懂!
    在C++里,变量就像是临时开的小仓库,可以用来存放各种数据。可是,不是所有变量都可以随便在哪儿都被访问到。它们都有自己的活动范围,也就是只有在特定区域才能被找到和使用。这种活动范围叫做作用域。而生命周期则是指这些变量“活着”的时间段,等生命周期结束,变量就会被自动清......