二分
二分分为整数二分和浮点数二分
1.整数二分
(整数二分有两种情况)
int bsearch_1(int l,int r)
{
while(l<r)
{
int mid=l+r>>1;
if(check1(mid)) l=mid+1;//向右寻找
else r=mid;
}
return l;
}
int bsearch_2(int l,int r)
{
while(l<r)
{
int mid=l+r+1>>1;
if(check2(mid)) l=mid;
else r=mid-1;//向左寻找
}
return l;
}
数的范围
https://www.acwing.com/problem/content/791/
#include<iostream>
using namespace std;
const int N=100010;
int a[N];
int fi(int k,int l,int r)
{
while(l<r)
{
int mid=l+r>>1;
if(a[mid]<k) l=mid+1;
else r=mid;
}
return l;
}
int en(int k,int l,int r)
{
while(l<r)
{
int mid=l+r+1>>1;
if(a[mid]<=k) l=mid;
else r=mid-1;
}
return l;
}
int main()
{
int n,q,k;
cin>>n>>q;
for(int i=1;i<=n;i++) cin>>a[i];
while(q--)
{
cin>>k;
int l=1,r=n;
int x=-1,y=-1;
if(a[fi(k,l,r)]==k) x=fi(k,l,r)-1;
if(a[en(k,l,r)]==k) y=en(k,l,r)-1;
cout<<x<<" "<<y;
if(q!=0) cout<<endl;
}
return 0;
}
2.浮点数二分
不涉及取整,所以直接二分即可
数的三次方根
https://www.acwing.com/problem/content/792/
#include<iostream>
using namespace std;
int main()
{
double n;
cin>>n;
double l=-100,r=100;
while(r-l>1e-8)
{
double mid=(l+r)/2;
if(mid*mid*mid<n) l=mid;
else r=mid;
}
printf("%.6f",l);
return 0;
}
递增三元组(二分,双指针,前缀和)
https://www.acwing.com/problem/content/description/1238/
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
int main()
{
int n;
scanf("%d",&n);
int a[n+1],b[n+1],c[n+1];
ll num=0;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++) scanf("%d",&b[i]);
for(int i=1;i<=n;i++) scanf("%d",&c[i]);
sort(a+1,a+n+1);
sort(b+1,b+n+1);
sort(c+1,c+n+1);
int k,l,r;
int mid,x=-1,y=-1;
for(int i=1;i<=n;i++)
{
x=-1,y=-1;
k=b[i];
l=1,r=n;
while(l<r)
{
mid=l+r+1>>1;
if(a[mid]<k) l=mid;
else r=mid-1;
}
if(a[l]<k) x=l;
else x=-1;
l=1,r=n;
while(l<r)
{
mid=l+r>>1;
if(c[mid]>k) r=mid;
else l=mid+1;
}
if(c[l]>k) y=l;
else y=-1;
if(x==-1||y==-1) continue;
else num+=(ll)x*(n-y+1);
}
cout<<num;
return 0;
}