整数二分
bs1,bs2分别对应两种需要查找的不同位置
bs1:查找最后一个true
int bs(int a[],int l,int r){//binary_search
while(l<r){
int mid=l+r>>1;
if(check(mid))l=mid;
else r=mid-1;
}
return l;
}
bs1:查找第一个false
int bs(int a[],int l,int r){//binary_search
while(l<r){
int mid=l+r>>1;
if(check(mid))l=mid+1;
else r=mid;
}
return l;
}
二分查找较为灵活,主要根据题目自行修改(感觉被模板没啥用,毕竟check还要自己写)
实数二分
double bs(double l,double r){
while(r-l>1e-8){
double mid=(l+r)/2;
if(check(mid))l=mid;
else r=mid;
}
return l;
}
例题
P1024 [NOIP2001 提高组] 一元三次方程求解
通过零点定理,实数二分查找
设,若,则中至少存在一个零点
#include<bits/stdc++.h>
using namespace std;
double a,b,c,d,ans=-101;
inline double f(double x){
return a*pow(x,3)+b*pow(x,2)+c*x+d;
}
int main(){
cin>>a>>b>>c>>d;
for(double x=-100;x<=99;x+=1){//查找区间[x,x+1)
if(f(x)*f(x+1)<=0){
double l=x,r=x+1,mid=(l+r)/2;
while(abs(f(mid))>1e-6){
mid=(l+r)/2;
if(f(mid)*f(l)<=0)r=mid;
else l=mid;
}
if(abs(l-ans)>=1){
printf("%.2lf ",l);
ans=l;
}//防止重复输出
}
}
}
解方程( 解方程 (nowcoder.com) )
考虑时间复杂度,满足时限,所以遍历a,b,二分查找c
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main(){
int n,a[1010],x;//0 1 5
cin>>n>>x;
for(int i=0;i<n;i++)cin>>a[i];
sort(a,a+n);
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
//c=-bx-ax^2
ll c=-a[i]*x*x-a[j]*x;
int l=0,r=n-1;
while(l<r){
int mid=l+r>>1;
if(c==a[mid]){cout<<"YES"; return 0;}
if(a[mid]<c)l=mid+1;
else r=mid-1;
}
}
}
cout<<"NO";
return 0;
}