二分查找
在一个排好序的数组中查找;
函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置
函数upper_bound()在first和last中的前闭后开区间进行二分查找,返回大于val的第一个元素位置。如果所有元素都小于val,则返回last的位置
lower_bound的源代码
int lower(LL *a,LL n,LL x){
LL l=0,r=n-1;
LL m;
while(l<r){
m=(l+r)/2;
if(a[m]<x) l=m+1;
else r=m;
}
if(a[l]>=x) return l;
else return -1;
}
upper_bound源代码;
int upper(LL *a,LL n,LL x){
LL l=0,r=n-1;
LL m;
while(l<r){
m=(l+r)/2;
if(a[m]<=x) l=m+1;
else r=m;
}
if(a[l]>x) return l;
else return n;
}
如果你想找看一道用二分做的题目 请点here
#include <cstdio>
#include <algorithm>
#include <iostream>
#define LL long long
using namespace std;
const int maxn=100017;
LL s[maxn],p[maxn],c[maxn];
int lower(LL *a,LL n,LL x){
LL l=0,r=n-1;
LL m;
while(l<r){
m=(l+r)/2;
if(a[m]<x) l=m+1;
else r=m;
}
if(a[l]>=x) return l;
else return -1;
}
int upper(LL *a,LL n,LL x){
LL l=0,r=n-1;
LL m;
while(l<r){
m=(l+r)/2;
if(a[m]<=x) l=m+1;
else r=m;
}
if(a[l]>x) return l;
else return n;
}
int main()
{
int T;
int n, m;
LL tt;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i = 0; i < n; i++)
{
scanf("%lld%lld",&s[i],&p[i]);
}
LL minn = 9999999999999999;
for(int i = n-1; i >= 0; i--)
{
minn = min(s[i]*p[i],minn);
c[i] = minn;
}
for(int i = 0; i < m; i++)
{
scanf("%lld",&tt);
if(tt>=s[n-1])//最后
printf("%lld\n",tt*p[n-1]);
else
{
int pos=upper(s,n,tt);
LL ans = tt*p[pos-1];
ans = min(ans,c[pos]);
printf("%lld\n",ans);
}
}
}
return 0;
}
用函数的方式;
#include <cstdio>
#include <algorithm>
#include <iostream>
#define LL long long
using namespace std;
const int maxn=100017;
LL s[maxn],p[maxn],c[maxn];
int main()
{
int T;
int n, m;
LL tt;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i = 0; i < n; i++)
{
scanf("%lld%lld",&s[i],&p[i]);
}
LL minn = 9999999999999999;
for(int i = n-1; i >= 0; i--)
{
minn = min(s[i]*p[i],minn);
c[i] = minn;
}
for(int i = 0; i < m; i++)
{
scanf("%lld",&tt);
if(tt>=s[n-1])//最后
printf("%lld\n",tt*p[n-1]);
else
{
int pos = upper_bound(s,s+n,tt)-s;
LL ans = tt*p[pos-1];
ans = min(ans,c[pos]);
printf("%lld\n",ans);
}
}
}
return 0;
}