http://www.yyycode.cn/index.php/2020/05/04/%e4%ba%8c%e5%88%86%e6%89%8b%e5%86%99%e6%a8%a1%e6%9d%bf3-0%e7%bb%8f%e9%aa%8c%e6%80%bb%e7%bb%93/
已经是第三次卡边界了..日
你要求的是满足条件的最小值, 所以当check满足时,应该往左搜。比如求最大值的最小化,往左搜,用第一个板子——P1462 通往奥格瑞玛的道路
如果要求满足条件的最大值,所以当check满足时,应该往右搜,比如求最小值的最大化,往右搜 —— 通信线路
然后边界[left,right], l=left-1,r=right+1;在求解实际问题时,用l==right+1(二分的实际含义)来判断无解的情况而不是用什么dis[n]==0x3f3f3f3f(达不到这个点来判断)[两道题合计8小时的教训];
2020/7/3上面的说法不对,在使用1号板子(r=mid),这个边界开[1,n+1];在使用二号板子,这个边界开[0,n]
然后去写check函数,用bool返回值比较容易想清楚—— 里面逻辑就是判断mid这个值能不能满足条件.如果满足就true,不满足就false;
如在p1462中,用的是第一个板子,然后check的时候,如果当前的mid满足就true;那么当前的mid怎么算满足呢,只要能走到就满足,所以是dis[n]<=b就是满足的
#include<iostream> #include<vector> #include<cstring> #include<algorithm> using namespace std; typedef long long LL; //找12222233的左边的2 ,取边界时l=left;r=right+1; int bsearch1(int l,int r) { while(l<r) { int mid=(l+r)/2; if(check[mid]) r=mid; else l=mid+1; } return l; } //找右边2,取边界是l=left-1;r=right; int bsearch2(int l,int r) { while(l<r) { int mid=(l+r+1)/2; if(check[mid]) l=mid; else r=mid-1; } return l; } int main(void) { return 0; }