首页 > 其他分享 >二分

二分

时间:2024-11-27 21:45:15浏览次数:9  
标签:二分 ... int mid 答案 模板

前言

答案属于一个区间,当这个区间很大时,暴力超时。但重要的是这个区间是对题目中的某个量有单调性的,此时,我们就会二分答案。每一次二分会做一次判断,看是否对应的那个量达到了需要的大小。

模板

模板1

while (l < r)
{
    int mid = l + r >> 1;	//(l+r)/2
    if (check(mid))  r = mid;    // check()判断mid是否满足性质
    else l = mid + 1;
}

模板2:

while (l < r)
{
    int mid = l + r + 1 >> 1;	//(l+r+1)/2
    if (check(mid))  l = mid;
    else r = mid - 1;
}

第一个模板是尽量往左找目标,第二个模板是尽量往右找目标。
只要是往左找答案,就用第一个模板,mid不用加一,r=mid,l加一;
只要是往右找答案,就用第二个模板,mid要加一,l=mid,r要减一;

模板3:(浮点二分)

while(r-l>1e-5) //需要一个精度保证
{
	double mid = (l+r)/2;
	if(check(mid)) l=mid; //或r=mid;
	else r=mid; //或l=mid;
}

浮点二分就相对简单多了,因为浮点除法不会取整,所以mid,l,r,都不用加1或减1.

函数

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int a[1000]={};
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	sort(a+1,a+1+n);
	for(int i=1;i<=n;i++)
	{
		cout<<a[i]<<" ";
	}
	cout<<endl;
	int m;
	cin>>m;
	for(int i=1;i<=m ;i++)
	{
		int b;
		cin>>b;
		cout<<lower_bound(a+1,a+1+n,b)-a<<endl;//第一个大于等于 无 返回>n
		cout<<upper_bound(a+1,a+1+n,b)-a<<endl;//第一个大于
		cout<<binary_search(a+1,a+1+n,b)<<endl;//有 1,无 0
	}
	return 0;
}

二分答案

如何判断一个题是不是用二分答案做的呢?

  1. 答案在一个区间内(一般情况下,区间会很大,暴力超时)
  2. 直接搜索不好搜,但是容易判断一个答案可行不可行
  3. 该区间对题目具有单调性,即:在区间中的值越大或越小,题目中的某个量对应增加或减少。

此外,可能还会有一个典型的特征:

求...最大值的最小 、 求...最小值的最大。

  1. 求...最大值的最小,我们二分答案(即二分最大值)的时候,判断条件满足后,尽量让答案往前来(即:让r=mid),对应模板1;
  2. 同样,求...最小值的最大时,我们二分答案(即二分最小值)的时候,判断条件满足后,尽量让答案往后走(即:让l=mid),对应模板2;

标签:二分,...,int,mid,答案,模板
From: https://www.cnblogs.com/-include-lmt/p/18573172

相关文章

  • 二分查找的区间到底是开还是闭?
    二分查找的区间到底是开还是闭?在这两个月的时间里,我似乎没有产出任何的有关知识点的文章,大多数都是题解相关的内容。以至于许多人觉得Macw07“失踪”了。本文是我来到北美之后的第一篇知识点文章,请大家多多关照。这次不讲难的知识点了,讲一个大家都熟悉的,但又非常令人抓毛的......
  • 二分查找2
    //1111111111.cpp:此文件包含"main"函数。程序执行将在此处开始并结束。///*http://oj.daimayuan.top/course/16/problem/60给一个序列a1,a2,…,an和m个询问。每次询问给出两个数l,x,求最大的r(r≤n)满足al+al+1+⋯+ar≤x。如果不存在这样的r,即al>x,输出......
  • ABAP开发学习——二分法查找问题记录
    在ABAP中使用二分法查找之前需要注意内表需要提前经过排序,尤其注意根据哪个字段使用BINARYSEARCH,就要针对哪个字段进行排序。使用两个及以上字段更要注意这一点,不可以用AB排序,再用BC去二分法查找,这样通常是读不到所需数据的。TYPES:BEGINOFty_data,field1TYP......
  • 整体二分做题记录
    0.前言1.5年前学过,没学好,回来加训。I.P3834【模板】可持久化线段树2板子题。时间复杂度\(\mathcal{O(n\log^2n)}\)。把\(\{a_i\}\)看作修改和后面的询问放一起,每次二分出答案值域上的\(mid\)后,如果修改的值\(\lemid\),那么BIT在\(i\)这个点上加\(1\);如果是询问......
  • 算法沉淀三:二分查找
    目录二分介绍 题目练习1.二分查找2.在排序数组中查找元素的第一个和最后一个位置3.搜索插入位置4.x的平方根5.山峰数组的峰顶6.寻找峰值7.搜索旋转排序数组中的最小值8.0~n-1中缺失的数字《剑指Offer53》 二分介绍 什么是二分查找?二分查找(BinarySearch),也......
  • 整体二分
    更新日志概念将所有询问离线下来,对这个整体进行二分答案。思路通用的思路是,考虑对于单个问题,如何二分答案。然后将所有二分答案压缩到一次二分答案之中。更详细地,我们将所有询问储存在一起,每次二分答案时,将询问分成两类:当前mid已满足的和未满足的。那么,下一次二分时,答......
  • 二分查找-C语言
    二分查找原理1.使用条件:线性表中的记录必须按关键码有序;必须采用顺序存储。 2.基本思想:在有序表中,取中间记录作为比较对象,若给定值与中间记录的关键码相等,则查找成功;若给定值小于中间记录的关键码,则在中间记录的左半区继续查找;若给定值大于中间记录的关键码,则在中间记录的......
  • 二分试题集
    #include<bits/stdc++.h>usingnamespacestd;#defineendl'\n'#definelllonglong#definelowbit(x)((x)&(-x))#definear2array<ll,2>#definear3array<ll,3>constintN=2e5+10;constintmod=1e9+7;consti......
  • LeetCode题解:29.两数相除【Python题解超详细,位运算、二分查找法、递归法】,知识拓展:位
    题目描述        给你两个整数,被除数 dividend 和除数 divisor。将两数相除,要求 不使用 乘法、除法和取余运算。整数除法应该向零截断,也就是截去(truncate)其小数部分。例如,8.345 将被截断为 8 ,-2.7335 将被截断至 -2 。返回被除数 dividend 除以除数 div......
  • C++,Java,Python,Javascript实现二分查找算法
    二分查找算法是一种在有序数组中查找特定元素的搜索算法。它的基本思想是将数组分成两半,通过比较中间元素与目标值来决定是在左半部分还是右半部分继续查找,从而逐步缩小查找范围直到找到目标值或者确定目标值不存在于数组中。下面是使用C++、Java、Python和JavaScript实现二......