二分查找-模板
二分要注意边界
有单调性的题目一定可以用二分,但没有的话也可能可以用二分
二分的L,R端点取在哪里在于答案是否包含mid


①中,答案在绿色线中,②中,答案在红色线中,注意,红绿色线不一定是紧挨的,他们只是情况是否满足而是
为什么mid要+1取?如果l=r-1,即r=l+1
那么mid会变成(2l+1) / 2=l,如果此时check恰好为true,那么会陷入死循环
所以分析问题可以先考虑答案在哪个区间,再接着考虑调整左右端点
方法1-推荐/常用
l , r
while(l <= r)
{
m = (l + r) / 2;
if(check())
{
ans = m;
l = m + 1;
}
else r = m - 1;
}
方法2
l , r
while(l < r)
{
m = (l + r) / 2;//左
if(check())
{
ans = m;
r = m;
}
else l = m + 1;
}
方法3
l , r
while(l < r)
{
m = (l + r) / 2 + 1;//右
if(check())
{
ans = m;
l = m;
}
else r = m - 1;
}
二分查找的模板 https://www.luogu.com.cn/problem/P8814 基于此题而写 此题答案(用到二分):
#include <bits/stdc++.h>
#define int long long
using namespace std;
int k, n, d, e;
signed main()
{
scanf("%lld", &k);
while (k--)
{
scanf("%lld%lld%lld", &n, &d, &e);
int x=n+2-d*e;//p+q
int L=1, R=(x>>1), mid=0, ans=0, q=0;
while (L<=R)
{
mid=((L+R)>>1); //p
q=x-mid;
if (q*mid<=n)
{
ans=mid;
L=mid+1;
}
else R=mid-1;
}
if (ans*(x-ans)==n) printf("%lld %lld\n", ans, x-ans);
else printf("NO\n");
}
return 0;
}
/*
题
qd=n
(q-1)(d-1)+1=de
n d e
770 5 77
q d
2 385
1
770 5 77
2 385
d e
393 3
32*39=1248
n d e
1248 393 3
q d
32 39
34 35
析
n+2-de=q+d
770+2-385=q+d (387) <-----
(q-1)(d-1)=de-1
(q-1)(d-1)=384
q d
2 385
3 384
. ...
. ...
. ...
193 194
(n+2-d*e)/2 至 (770+2-385)-((n+2-d*e)/2)
*/
浮点数二分:例子,求开平方根,sqrt(x)
少了麻烦的边界条件,直接赋值即可
#include <bits/stdc++.h>
using namespace std;
double x, L, R;
int main()
{
scanf("%lf", &x);
L=0, R=x;
while (R-L>1e-8) //精度相差极小,即可退出 可以换成 for (int i=1; i<=100; i++),推荐while
{
double mid=(L+R)/2;
if (mid*mid>=x) R=mid;
else L=mid;
}
printf("%.5lf", L);
return 0;
}

浙公网安备 33010602011771号