二分
cpp
//模板
a[N]; //存数据
int l=-1,r=n;
while(l+1<r){
int mid=l+r>>1;
if(a[mid]<ans or a[mid]<=ans) l=mid;
else r=mid;
}
return l or r;
示例
如何确定两个or处的选择,应该按照答案所处的边界位置划分为两个区域,暂且称之为含答案区域(绿色区域)与非含答案区域(白色)比如对于数据 1 2 2 3 3 3 5
1.找到第一个3的位置,绿色区域为 3 3 3 5,可以看出r指针会指向最终答案3(while结束的条件是l+1==r,二分结束后l与r指针分别指向左右边界的位置),所以l不可能是答案,所以第一个or的位置就是a[mid]< 3
2.找到最后一个3的位置,绿色区域为 1 2 2 3 3 3,可以看出l指针会指向最终答案3,所以第一个or处选择a[mid]<=3
3.找到比3小的最大的数,绿色区域为 1 2 2,可以看出l指针会指向最终答案2,所以第一个or处选择a[mid]< 3(因为最后l指针要指向答案,不能指向3所以不能带=)
4.找到比3大的最小的数,绿色区域为 5,可以看出r指针会指向最终答案5,所以第一个or处选择a[mid]<=3(因为r指针要指向最终答案,不能指向3)
cpp
#include<iostream>
using namespace std;
const int N=1e5+10;
int a[N];
int n;
int main(){
cin >> n;
for(int i=1;i<=n;i++) cin >> a[i];
int l=0,r=n+1;
// //找到第一个3的位置
// while(l+1<r){
// int mid=l+r>>1;
// if(a[mid]<3) l=mid;
// else r=mid;
// }
// cout <<r;
// //找到最后一个3的位置
// while(l+1<r){
// int mid=l+r>>1;
// if(a[mid]<=3) l=mid;
// else r=mid;
// }
// cout << l;
// //找到比3小的最大的数
// while(l+1<r){
// int mid=l+r>>1;
// if(a[mid]<3) l=mid;
// else r=mid;
// }
// cout << l;
//找到比3大的最小的数
while(l+1<r){
int mid=l+r>>1;
if(a[mid]<=3) l=mid;
else r=mid;
}
cout << r;
return 0;
}
cpp
#include<iostream>
using namespace std;
const int N=1e5+10;
int a[N];
int q,n;
int main(){
cin >> n >> q;
for(int i=1;i<=n;i++) cin >> a[i];
while(q--){
int ans;
cin >> ans;
int l=0,r=n+1;
while(l+1<r){
int mid=l+r>>1;
if(a[mid]<ans) l=mid;
else r=mid;
}
if(a[r]!=ans) {
cout << "-1 -1" << endl;
continue;
}
cout << r-1 <<" ";
l=0,r=n+1;
while(l+1<r){
int mid=l+r>>1;
if(a[mid]<=ans) l=mid;
else r=mid;
}
cout << l-1 << endl;
}
return 0;
}
cpp
#include<iostream>
#include<cmath>
using namespace std;
double ans;
int main(){
cin >> ans;
double l=-10001,r=10001;
while(abs(l*l*l-ans)>1e-9){
double mid=(l+r)/2;
if(mid*mid*mid<ans) l=mid;
else r=mid;
}
printf("%.6f",l);
return 0;
}
cpp
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int l=-1,r=nums.size();
while(l+1<r){
int mid=l+r>>1;
if(nums[mid]<=target) l=mid;
else r=mid;
}
if(l==-1) return 0;
if(nums[l]!=target){
return l+1;
}
return l;
}
};
cpp
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int l=-1,r=nums.size();
nums.push_back(1e9+10); //防止溢出
while(l+1<r){
int mid=(l+r)>>1;
if(nums[mid]<target) l=mid;
else r=mid;
}
int begin=r;
if(nums[r]!=target){
return {-1,-1};
}
l=-1,r=nums.size();
while(l+1<r){
int mid=(l+r)>>1;
if(nums[mid]<=target) l=mid;
else r=mid;
}
int last=l;
return {begin,last};
}
};