Blue Bridge Cup Essential Algorithm 2: Binary Search

binary search

[The following programs all search for x in the interval [l, r], and the default data order is non-decreasing]

1. The subscript of a number in the binary search interval

The subscript of a number in the binary search interval (existing and unique), if it does not exist, return -1:

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

This should be the best written dichotomy

2. The maximum value of <= x in the query interval

Query the maximum value of <=x in the interval (return the rightmost coordinate when there are multiple maximum values):

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

Not much to say about the two-point process, but pay attention to two points:

  1. Assuming that you want to query on [l,r], the recommended parameter to be passed in is l-1.r, so if the return value is l-1, it means that there is no value <=x, or you can choose to judge before the two points, Divide again when it is determined that a solution exists.
  2. mid=(l+r+1)>>1 instead of mid=(l+r)>>1, if the latter method is adopted, suppose the interval is reduced to 2, 3, then mid=2, then if a[mid]<=x is established, then l=mid, which will become an infinite loop, so +1 is divided by 2.

3. The minimum value of >=x in the query interval

Query the minimum value >=x in the interval (return the leftmost coordinate when there are multiple minimum values):

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

It's just that the conditions have become r=mid and l=mid+1, so mid should be changed to mid=(l+r)>>1, otherwise it will be an infinite loop. The query interval [l, r] is passed as parameters l, r+1, and the return value is r+1 as no solution.
In this way, as long as the upper and lower bounds and the conditions of taking the middle are well controlled, it can be divided into two.

4. Divide real numbers

Dichotomies on real numbers are easier to write. Just control the boundaries according to the accuracy required by the topic. Generally, there will be no infinite loop.

while (fabs(r-l)>EPS)//EPS是题目要求的精度
{
    
    
	mid=(l+r)/2;
	if(check(mid)) l=mid;
	else r=mid;
}

Five, practice questions

1. Network cable supervisor

Topic description and input and output

insert image description here
input Output:

输入:
4 11
8.02
7.43
4.57
5.39
输出:
2.00

Topic ideas and codes

Idea: Here is to directly divide into two points to judge whether it matches the result! ! ! Pay attention to special cases to make judgments, that is, cases that cannot be divided.
Code:

#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll maxn=1e5+10;
const ll maxm=1e8+10;
const ll mod=1e9+7;
ll n,m;
ll a[maxn];
ll mx;
ll check(ll x){
    
    
    ll res=0;
    for(int i=1;i<=n;i++){
    
    
        res+=a[i]/x;
    }
    return res;
}
int main(){
    
    
    cin>>n>>m;
    ll sum=0;
    for(int i=1;i<=n;i++){
    
    
        double s;
        cin>>s;
        a[i]=s*100;
        mx=max(a[i],mx);
        sum+=a[i];
    }
    
    if(m>sum){
    
    
        printf("0.00");
        return 0;
    }
    ll l=1,r=mx;
    ll ans=0;
    while(l<r){
    
    
        ll mid=(l+r+1)>>1;
        if(check(mid)>=m){
    
    
            l=mid;
        }
        else{
    
    
            r=mid-1;
        }

    }
    printf("%.2lf",l*1.0/100);
	return 0;
}

2. Borrow a classroom

Topic description and input and output

insert image description here

input Output:

输入:
4 3
2 5 4 3
2 1 3
3 2 4
4 2 4
输出:
-1
2

Topic ideas and codes

Idea: The first is the interval modification. Here, the difference is used to solve the problem, and the result interval is narrowed by bisection! ! !
Dichotomous and differential codes

#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll maxn=1e5+10;
const ll maxm=1e8+10;
const ll mod=1e9+7;
int line[1000010], l[1000010], r[1000010], d[1000010], change[1000010],sum[1000010];
int n,m;
int check(int x)
{
    
    
	memset(change,0,sizeof(change));

	for (int i = 1; i <= x; i++)
	{
    
    
        change[l[i]]+=d[i];
        change[r[i]+1]-=d[i];
	}

	for (int i = 1; i <= n; i++)
		sum[i]=sum[i-1]+change[i];
		//obj 2抹平差分数组

	for (int i = 1; i <= n; i++)
		if(sum[i]>line[i])return false;
		//obj 3什么情况下是发生了问题?

	return true;
}
int main(){
    
    
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= n; i++)
		scanf("%d", &line[i]);
	for (int i = 1; i <= m; i++)
		scanf("%d %d %d", &d[i], &l[i], &r[i]);

	if(check(n))
	{
    
    
		printf("0");
		return 0;
	}

	int l = 1, r = n, mid=0;
	while(l<r)
	{
    
    
		mid = (l + r) >> 1;
		if(!check(mid))//obj 5
			r=mid;
		else
			l=mid+1;
        //cout<<l<<" "<<r<<" "<<check(mid)<<endl;
	}
	printf("-1\n");
	printf("%d", l);

	return 0;
}

Tree array code:

#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll maxn=1e5+10;
const ll maxm=1e8+10;
const ll mod=1e9+7;
int line[1000010], l[1000010], r[1000010], d[1000010], t[1000010],ti[1000010];
int n,m;
int lowbit(int n){
    
    
    return n&(-n);
}
void update(int x,int val){
    
    
    for(int i=x;i<=n;i+=lowbit(i)){
    
    
        t[i]+=val;
        ti[i]+=val*x;
    }
}
int getsum(int x){
    
    
    int sum=0;
    for(int i=x;i;i-=lowbit(i)){
    
    
        sum+=(x+1)*t[i]-ti[i];
    }
    return sum;
}
int pan(){
    
    
    int ans=0;
    for(int i=1;i<=n;i++){
    
    
        int sum=getsum(i)-getsum(i-1);
        if(sum>line[i])return 0;
    }
    return 1;
}
int main(){
    
    
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= n; i++)
		scanf("%d", &line[i]);
    int f=0;
	for (int i = 1; i <= m; i++)
    {
    
    
        scanf("%d %d %d", &d[i], &l[i], &r[i]);
        update(l[i],d[i]);
        update(r[i]+1,-d[i]);
        if(f)continue;
        if(!pan()){
    
    
            f=i;
        }
    }
    if(f)printf("-1\n%lld",f);
    else{
    
    
        printf("0");
    }
	return 0;
}

Six, a paragraph of recommendation to everyone


"If you are undecided, you can ask the spring breeze, and if the spring breeze does not speak, you will follow your heart" means: if you are hesitant about something, ask the spring breeze how to do it. . "When you are undecided, you can ask the spring breeze, and if the spring breeze does not speak, you will follow your heart." The sentence comes from the "Sword Comes" by the online writer "Fenghuo Opera Princes". The original text is: "If you are undecided, you can ask the spring breeze. Follow your heart".

insert image description here


Guess you like

Origin blog.csdn.net/weixin_46627433/article/details/123538537