首页 > 其他分享 >二分的边界问题

二分的边界问题

时间:2023-09-06 12:56:12浏览次数:42  
标签:二分 半边 int 边界问题 mid 区间 模板

二分法的适用场景

1. 有单调性的题目一定可以二分

2. 没有单调性也有可能二分

由此可见,二分的核心并不是单调性。

核心是:定义了某种性质,使得可以将整个数据集一分为二,左半边满足一种性质,右半边不满足;右半边满足另一种性质,左半边不满足。则二分可以寻找左区间的边界,也可以寻找右区间的边界。

 

二分法的边界问题非常重要,稍不注意就可能会死循环。

二分法有两个模板,两个模板最核心的区别是:取中点时,mid = (l + r) / 2  or  mid = (l + r + 1) / 2  

两个模板

// 区间[l, r]被划分成[l, mid]和[mid + 1, r]时使用
int bsearch_1(int l, int r) {
    // 由于区间的划分对右区间不利,因此mid要稍微取小一些
    while(l < r) {
        int mid = l + r / 2;
        if(check(mid)) r = mid  // check()判断mid是否满足性质
        else l = mid + 1;
    }
   return l; } // 区间[l, r]被划分成[l, mid - 1]和[mid, r]时使用 int bsearch_2(int l, int r) { while(l < r) { // 由于区间的划分对左区间不利,因此mid要稍微取大一些 int mid = (l + r + 1) / 2; if(check(mid)) l = mid; else r = mid - 1; } return l; }

两个模板的选择问题

1. 如果求左区间的终点(mid属于左区间,即区间划分方式为[l, mid]和[mid + 1, r]),第二个模板

2. 如果求右区间的起点(mid属于右区间,即区间划分方式为[l, mid - 1]和[mid, r]),第一个模板

苦难点在于mid = (l + r) / 2  or  mid = (l + r + 1) / 2  的选择。

技巧

难点在于mid是否+1.首先先不用管mid,而是确定是取左半边的区间终点还是右半边的起点。如果是左半边,那么l = mid, or r = mid - 1,如果出现了mid-1,说明左区间在区分划分上吃亏了,那么我们需要尽可能的将mid大一些,如此才能平衡左区间的吃亏。因此,mid=(l+r+1)/2.
否则,如果是取右半边的区间起点,那么r = mid, l = mid + 1,如此左区间沾光有区间吃亏,因此需要让mid取得稍微左一些即(l+r)/2才能平衡。

标签:二分,半边,int,边界问题,mid,区间,模板
From: https://www.cnblogs.com/luxiayuai/p/17682013.html

相关文章

  • 二分法demo
    1.python实现frommathimportfloorarr=[1,2,3,4,5,6,8,9,10,11]left=0right=len(arr)-1res=7while(left<=right):mid=floor((left+right)/2)if(arr[mid]<res):left=mid+1elif(arr[mid]>res):......
  • Java 二分查找
    思路问题描述:在采用顺序存储结构的有序数组中,查找目标元素,如果目标元素存在,返回对应的数组下标。假设查找的有序数组为升序,二分查找采用以下的思路进行解决:将数组中间位置的元素与目标元素比较,如果二者相等,则查找成功;否则,从中间位置将数组分为前、后两个数组;如果中间位置......
  • 二分法及其变体问题
    描述给定一个n个元素有序的(升序)整型数组nums和一个目标值target,写一个函数搜索nums中的target,如果目标值存在返回下标,否则返回-1。示例1:输入:nums=[-1,0,3,5,9,12],target=9输出:4解释:9出现在nums中并且下标为4示例2:输入:nums=[-1,0,3,......
  • 「突刺贯穿第二分块」P4117 [Ynoi2018] 五彩斑斓的世界
    很帅气!分块在线转离线,考虑每个块对于询问的贡献。维护块的max和tag分别代表最大值和减了多少。先考虑整块,\(max<2*x:\)每次暴力区间平移即可。否则对于\([1,x]\)全部加上\(x\)平移到\([x+1,x*2]\),然后区间整体减\(x\)即可。散块怎么做?暴力减,然后重构块......
  • 【学习笔记】二分图基础
    二分图与网络流基础(网络流待学)查看目录目录前置知识:二分图:二分图的定义:二分图的判定:例题:[NOIP2010提高组]关押罪犯二分图的匹配:匈牙利算法:例题:[ABC317G]Rearranging[ABC317G]Rearranging前置知识:tarjan强连通分量:有向图中几个点可以相互到达,就称这几个点是强连通......
  • Leetcode刷题笔记——二分法
    二分法是搜索算法中极其典型的方法,其要求输入序列有序并可随机访问。算法思想为输入:有序数组nums,目的数值target要求输出:如果target存在在数组中,则输出其index,否则输出-1将原数组通过[left,right]两个索引划分范围,初值left=0,right=数组的最后一个元素当left<=right时mid......
  • 二分查找(两种模板)/高精度 (加 减) 计算模板(2023/8/30)
    //二分查找(两种模板)#include<iostream>usingnamespacestd;#defineN100001inta[N];intmain(){intn,m;cin>>n>>m;for(inti=0;i<n;i++)scanf("%d",&a[i]);while(m--){intx;scanf("%d"......
  • hdu:Machine Schedule(二分图匹配)
    ProblemDescriptionAsweallknow,machineschedulingisaveryclassicalproblemincomputerscienceandhasbeenstudiedforaverylonghistory.Schedulingproblemsdifferwidelyinthenatureoftheconstraintsthatmustbesatisfiedandthetypeof......
  • 数组二分查找:35. 搜索插入位置、34. 在排序数组中查找元素的第一个和最后一个位置
    35. 搜索插入位置1classSolution:2defsearchInsert(self,nums:List[int],target:int)->int:3left,right=0,len(nums)-145whileleft<=right:#左闭右闭6mid=left+(right-left)//27ifnum......
  • 二分算法
    将两个集合合并询问两个元素是否在一个集合当中基本原理:每个集合用一棵树表示,树根的编号就是整个集合的编号。每个节点储存它的父节点,p[x]表示x的父节点判断树根(属于那个集合)if(p[x]==x)求x的集合编号:while(p[x]!=x)x=p[x];合并两个集合:px是x的集合编号,py是y的......