二分
整数集合上的二分
本文章的二分写法保证最终答案出于闭区间[l,r]以内,循环以l=r结束,每次二分的中间值mid会归属左半段与右半段二者之一
在单调递增序列a中查找>=x的数中最小的一个(即x或x的后继):
1.答案出于闭区间[l,r]以内,循环以l=r结束:
写法1:
int func(int l,int r,int x) {
while (l < r) {
int mid = (l + r) >> 1;
if (a[mid] >= x)r = mid;
else l = mid + 1;
}
return a[l];
}
写法2:
int func2(int l, int r, int x) {
while (l < r) {
int mid = (l + r + 1) >> 1;
if (a[mid] <= x)l = mid;
else r = mid - 1;
}
return a[l];
}
2.答案出于闭区间[l,r]以外,循环以l=r+1结束
int func3(int l, int r,int x)
{
int mid;
while (l <= r)
{
mid = (l + r) / 2;
if (a[mid] == x) return a[mid];
else if (a[mid] > x) r = mid - 1;
else l = mid + 1;
}
cout << "can't find" << endl;
return l;//返回长度 r+1
}
例如:最长上升子序列:
#include<iostream>
using namespace std;
int a[100],dp[100];
int func3(int l, int r,int x)
{
int mid;
while (l <= r)
{
mid = (l + r) / 2;
if (dp<