HELLO WORLD--一起加油(🍺)!|

kingwzun

园龄:3年6个月粉丝:111关注:0

2022-08-06 19:37阅读: 87评论: 0推荐: 0

二分算法

整数二分

二分的本质不是单调性。
(有单调性一定可以二分,但是二分可以做的题,不一定需要满足单调性。)
二分的本质是二段性
就是有一个分界点O,分界点左边都是状态x,分界点右边都是状态y。
image

通过二分就可以找到红色区域的右边界值或者绿色区域的左边界值
每次保证我们区间内有答案。

O点就是我们想求的答案点,绿色是满足性质的区域,红色是不满足性质的区域。

求右分界点模板

当想找不满足性质的边界值(红色区域的右边界值)
例如:
求递增序列中,求小于10的最大值。
check函数就是:mid<10

过程:

  1. 找中间值 mid=l+r+12 计算mid时需要加1

  2. if(check(mid))等于true或者是false
    check(m)检查是不是在红色区间。

    • 如果在红色区间(true) 正确区间为:[mid,r] ==> l=mid
    • 否则不在区间返回 : false 正确区间为:[l,mid1] ==> r=mid-1

为什么需要+1?
原因是如果不加上1,那么mid得到的是下取整的数,那么有可能[m,r]更新过后m会一直等于m(m+1==r的情况)会陷入死循环

代码:

int bsearch(int l, int r)
{
while(l<r){
int mid=l+r+1 >>1;
if(a[mid]<=k) l=mid;
else r=mid-1;
}
}

求左分界点模板

当想找满足性质的边界值(绿色区域的左边界值)
例如:
求递增序列中,求大于10的最小值。
check函数就是:mid>10

过程:

  1. 找中间值 mid=l+r2

  2. if(check(mid))等于true或者是false
    check(m)是检查m是在满足绿颜色区间的性质(检查是不是在绿色区间)

    • 如果是true 正确区间:[lmid] ==> r=mid
    • 如果是false 正确区间:[mid+1,r] ==> l=mid+1

代码:

int bsearch(int l, int r)
{
while(l<r){
int mid=l+r >>1;
if(a[mid]>=k) r=mid;
else l=mid+1;
}
}

模板题

题目:
给定一个按照升序排列的长度为 n 的整数数组,以及 q 个查询。

对于每个查询,返回一个元素 k 的起始位置和终止位置(位置从 0 开始计数)。

如果数组中不存在该元素,则返回 -1 -1。

代码:

const int N = 2e6 + 10;
int n,m, a[N];
void solve(){
cin>>n>>m;
for(int i=0;i<n;i++)
cin>>a[i];
while(m--){
int k;cin>>k;
int l,r;
//找左边界
l=0,r=n-1;
while(l<r){
int mid=l+r >>1;
if(a[mid]>=k) r=mid;
else l=mid+1;
}
int ans1=r;
//找右边界
l=0,r=n-1;
while(l<r){
int mid=l+r+1 >>1;
if(a[mid]<=k) l=mid;
else r=mid-1;
}
int ans2=r;
if(a[ans1]==k) {
cout<<ans1<<" "<<ans2<<endl;
}
else cout<<"-1 -1"<<endl;
}
}

浮点数二分

和整数一样,while循环时换成r - l > 精度即可。

而且因为是浮点数,不需要考虑 +1 -1 之类的。

代码:

int bsearch(double l, double r)
{
while(r - l > 精度){
double mid=(l+r)/2;
if(check(mid)) r=mid;
else l=mid;
}
}

应用

平均值问题

平均值问题一般都是二分。
问题描述:
给定序列a,判断是否存在一个方案,使其平均值大于等于avg

方法:
二分平均值,使a的所有元素减去avg。
看否是存在长度大于F的一段串的和 >=0

本文作者:kingwzun

本文链接:https://www.cnblogs.com/kingwz/p/16556555.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   kingwzun  阅读(87)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起