功能:在一个长度为 n 的数组中 查询某个值 在这个数组中的位置。
时间复杂度: log2(n)
下面的算法应该使用于有序数组(升序),返回 [left, right) 范围内 最后一个小于等于 e 的数 的下标 。
EG: b[5] = {1, 2, 3, 3, 5}; find(0, 5, 3) = 4
数组
int find(int left,int right, ll e) {
int mid;
while(left < right) {
mid = (left+right)/2;
(e < b[mid]) ? right = mid : left = mid + 1; // 数组 b[] 为全局变量,可根据实际用法自行更改
}
return left-1;
}
用一个题目,验证一下:
题目链接:传送门
参考代码:
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
const int N = 200100;
ll a[N];
ll b[N];
int find(int left,int right, ll e) {
int mid;
++right;
while(left < right) {
mid = (left+right)/2;
(e < b[mid]) ? right = mid : left = mid + 1;
}
return left-1;
}
int main()
{
int n, m;
ll sum = 0;
cin >> n >> m;
b[0] = 0;
for(int i=1; i<=n; ++i) {
scanf("%I64d", &a[i]);
sum += a[i];
b[i] = a[i] + b[i-1];
}
ll now = 0, temp;
int cnt = 0;
for(int i=1; i<=m; ++i) {
scanf("%I64d", &temp);
now += temp;
if(now >= sum) {
cout << n << endl;
now = 0;
continue;
}
cnt = find(0, n, now);
if(b[cnt] - now > 0)
cout << n-cnt+1 << endl;
else
cout << n-cnt << endl;
}
return 0;
}