I want to find the largest element that is smaller than x
in a sorted array, where the differences between the consecutive elements of the array are non-decreasing.
For example:
[1, 3, 10, 17, 50, 1000]
is a valid input , because the consecutive differences(2,7,7,33,950)
are in increasing order.
[1, 3, 4, 10, 18]
is not a valid input, as the consecutive differences(2, 1, 6, 8)
are not in increasing order.
The optimum solution is O(log(log max_value))
, so I am looking for better solutions than upperbound/ binary search. Actually ,I am looking to optimize binary search from O(log N)
to O(log(log max_value)
.
#include <bits/stdc++.h>
using namespace std;
const int n = 50000001;
int arr[n];
int binarysearch_lowerbound(int begin, int end, int x)
{
int ans = end;
while (begin < end) {
int mid = (begin + end) / 2;
if (arr[mid] >= x) {
ans = mid;
end = mid;
}
else {
begin = mid + 1;
}
}
return ans;
}
int main()
{
int N;
cin >> N;
for (int i = 0; i < N; i++) {
cin >> arr[i];
}
int q;
cin >> q;
for (int i = 0; i < q; i++) {
int x;
cin >> x;
int k;
int begin = x / (arr[N - 1] - arr[N - 2]);
int end = x / (arr[1] - arr[0]);
if (end > N - 1) {
end = N;
}
k = binarysearch_lowerbound(begin, end, x);
cout << arr[k - 1] << endl;
}
return 0;
}