基本二分法
#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;
//严格递增,不存在返回-1
int b_search(const vector<int>& a,int x){
int l=0,r=a.size()-1;
int mid;
while(l<=r){
mid=(l+r)/2;
if(A[mid]==x)return mid;
else if(A[mid]>x)r=mid-1;
else l=mid+1;
}
return -1;
}
// >=x 的第一个元素,可重复,不存在返回假定位置
int lower_bound(const vector<int>& a,int x){
int l=0,r=a.size();
int mid;
while(l<r){
mid = (l+r)/2;
if(x<=a[mid]){
r=mid;
}else{
l=mid+1;
}
}
return l;
}
// >x 的第一个元素,可重复,不存在返回假定位置
int upper_bound(const vector<int>& a,int x){
int l=0,r=a.size();
int mid;
while(l<r){
mid = (l+r)/2;
if(x<a[mid]){
r=mid;
}else{
l=mid+1;
}
}
return l;
}
// 通用二分法
int solve(){
int l,r;//l...r 覆盖所有可能
int mid;
while(l<r){//l->r 不满足 -> 满足
mid=(l+r)/2;
if(ok){//满足要求的情况
r=mid;
}else{
l=mid+1;
}
}
return l;//返回夹出来的位置
}
void exec(){
int n;cin>>n;
vector<int> a(n);
for(int i=0;i<n;i++)cin>>a[i];
int x;
cin>>x;
int ans1 = lower_bound(a,x);
int ans2 = upper_bound(a,x);
cout<<ans1<<endl;
cout<<ans2<<endl;
}
int main(){
freopen("data.in","r",stdin);
exec();
return 0;
}
扩展二分法
#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;
const double eps = 1e-5;
double f(double x){return x*x-2;}
//这里不再是左边不满足,右边满足。
//而变成了两边不满足,中间满足。
double solve(){
double l=1,r=2,mid;
while(r-l>eps){
mid=(l+r)/2;
if(f(mid)>0){
r=mid;
}else{
l=mid;
}
}
return mid; //返回中间
}
double f2(double h){
}
double ton(){
double left=0,right=R;
double mid;
while()
}
void exec(){
cout<<solve()<<endl;
}
int main(){
freopen("data.in","r",stdin);
exec();
return 0;
}