二分ルックアップコード実装
機能:長さnの配列で、この配列の値の位置をクエリーします.
時間複雑度:log 2(n)
次のアルゴリズムは、秩序配列(昇順)に使用され、[left,right)範囲内の最後のeに等しい数以下の下付き記号を返すべきである.
EG: b[5] = {1, 2, 3, 3, 5}; find(0, 5, 3) = 4
はいれつ
1つの問題で検証します.
タイトルリンク:転送ゲート
参照コード:
時間複雑度:log 2(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;
}
1つの問題で検証します.
タイトルリンク:転送ゲート
参照コード:
#include
#include
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;
}