D - Forbidden List 2 解説 by en_translator
Observations
Since the order of \(A\) does not affect the answer, we sort it in ascending order to assume \(A_1 < A_2 < \dots < A_N\). For convenience, we define sentinels as \(A_0 = -\infty, A_{N+1} = +\infty\).
First, we find the minimum value of \(A\) that is greater than or equal to \(X\) using binary search. Let \(A_s\) be this value.
When an integer is greater than or equal to \(X\) and not contained in \(A\), we simply call it a good integer.
For \(s \leq t \leq N+1\), there are \((A_t - x + 1)\) integers between \(X\) and \(A_t\) (inclusive), and \((t - s + 1)\) of them are contained in \(A\). Thus, the number of integers between \(X\) and \(A_t\) (inclusive) that are not contained in \(A\) is \((A_t - x + 1) - (t - s + 1)\). This is weakly monotonically increasing with respect to \(t\), so one can use binary search to find \(t_{r}\) such that:
- \((A_{t_r - 1} - x + 1) - ((t_r - 1) - s + 1) < Y\),
- \((A_{t_r - 0} - x + 1) - ((t_r - 0) - s + 1) \geq Y\).
For this \(t_r\), there are strictly less than \(Y\) good integers not exceeding \(A_{t_{r} - 1}\), and \(Y\) or more good integers not exceeding \(A_{t_r - 0}\), so the answer is between \(A_{t_{r} - 1}\) and \(A_{t_r - 0}\), exclusive. If we denote the answer by \(x_{ans}\), there are \((t_r - s)\) integers between \(X\) and \(x_{ans}\) (inclusive) that are contained in \(A\), so the answer is \(x_{ans} = X + (Y-1) + (t_r - s)\).
Sample code (C++)
#include <iostream>
using std::cin;
using std::cout;
#include <vector>
using std::vector;
#include <algorithm>
using std::sort;
using std::lower_bound;
typedef long long int ll;
ll n, q;
vector<ll> a;
void solve () {
sort(a.begin(), a.end());
for (ll qi = 0; qi < q; qi++) {
ll x, y;
cin >> x >> y;
// a[0, si) < x && a[si, n) >= x
ll si = lower_bound(a.begin(), a.end(), x) - a.begin();
// youngest ti where |{x, x+1, ..., a[ti]} - {a[si], a[si+1], ..., a[ti]}| >= y
ll ti;
{
ll ok = n, ng = si-1;
while (ng + 1 < ok) {
ll med = (ok + ng) / 2;
if ((a[med] - x + 1) - (med - si + 1) >= y) {
ok = med;
} else {
ng = med;
}
}
ti = ok;
}
ll ans = x + (y-1) + (ti - si + 0);
cout << ans << "\n";
}
}
int main (void) {
std::cin.tie(nullptr);
std::ios_base::sync_with_stdio(false);
cin >> n >> q;
a.resize(n);
for (ll i = 0; i < n; i++) {
cin >> a[i];
}
solve();
return 0;
}
投稿日時:
最終更新: