功能:在一个长度为 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; }