Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
Focus on where two consecutive required values and are matched inside . The rest of the problem is just stitching those local gaps together.
If , a shortest valid walk from one value to the other has exactly steps, so every intermediate value is forced.
If , the two matched positions cannot be adjacent, because adjacent equal values violate . The shortest bridge is , so the middle position is not fixed.
The positions of all required in every minimum-length are fixed: start at position , then add the shortest bridge length for each neighboring pair.
Build blocks: fixed anchor blocks of length for each , and gap blocks between them. Gap length is if different, otherwise ambiguous slot. Prefix sums plus binary search answer each query.
Research note: I checked the canonical Codeforces statement at https://codeforces.com/contest/2199/problem/E, the official Kotlin Heroes 14 tutorial page at https://codeforces.com/blog/entry/151783, and the contest status page at https://codeforces.com/contest/2199/status. The official page's solution uses exactly this block/prefix-sum idea; the explanation below is original.
A useful way to strip the problem down: a beautiful array is a shortest walk on the integer line that visits in order. Adjacent elements of differ by , so each move changes the current value by one.
Suppose and are matched at positions in .
If , then in moves, the value can change by at most , so . This bound is tight: just move monotonically from to . That gives
u, u+\operatorname{sgn}(v-u), u+2\operatorname{sgn}(v-u), \dots, v.$$ So the intermediate values are completely forced. No wiggle room, no clever detour, no magic bullshit. If $u=v$, the two occurrences must be at different positions. They cannot be adjacent, because then their difference would be $0$, not $1$. Therefore we need at least two moves: $v\to v+1\to v$ or $v\to v-1\to v$. This uses exactly one inserted element, but that inserted element is not unique. Also, do not assume $b_i$ must be positive just because $a_i$ is positive; the statement only bounds $a_i$. Define the shortest number of moves between consecutive required values asd_i=\begin{cases} |a_i-a_{i+1}|, & a_i\ne a_{i+1},\ 2, & a_i=a_{i+1}. \end{cases}
Any valid $b$ containing $a$ has matched positions $p_1<\dots<p_n$, sop_{i+1}-p_i\ge d_i.
Extra elements before $p_1$ or after $p_n$ are useless and can be removed, so in a minimum-length array we have $p_1=1$ andm=1+\sum_{i=1}^{n-1} d_i.
The lower bound is achievable by concatenating the shortest bridges for every neighboring pair, overlapping endpoints. Therefore the positions of all anchors $a_i$ are fixed in every beautiful array. Now split the whole answer line into blocks: - an anchor block of length $1$ for each $a_i$; - between $a_i$ and $a_{i+1}$: - if they differ, a gap block of length $|a_i-a_{i+1}|-1$ containing the forced intermediate values; - if they are equal, a gap block of length $1$ whose value is ambiguous, so queries there answer $0$. For example, between $4$ and $1$ the forced block is $3,2$. Between $1$ and $1$ there is one ambiguous slot: it can be $0$ or $2$, so the answer is $0$. Store all block lengths and their prefix sums. For a query position $x$: 1. If $x>m$, answer $-1$. 2. Otherwise find the first prefix sum at least $x$ using binary search. That tells us which block contains $x$. 3. If it is an anchor block, output the corresponding $a_i$. 4. If it is an equal-pair gap, output $0$. 5. Otherwise it is a forced monotone gap. If the left endpoint is $u$ and the direction is $s\in\{-1,1\}$, and the offset inside the gap is $t$, output $u+s\cdot t$. Zero-length forced gaps happen when $|a_i-a_{i+1}|=1$; they are harmless. Prefix sums may repeat, but `lower_bound` still lands on the previous non-empty block for real positions. Complexity: building the blocks is $O(n)$, each query is $O(\log n)$, and memory is $O(n)$.#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int n, q;
cin >> n >> q;
vector<ll> a(n);
for (ll &v : a) cin >> v;
vector<ll> len(2 * n - 1, 1);
for (int i = 0; i + 1 < n; ++i) {
if (a[i] != a[i + 1]) len[2 * i + 1] = llabs(a[i + 1] - a[i]) - 1;
}
vector<ll> pref(2 * n, 0);
for (int i = 0; i < (int)len.size(); ++i) {
pref[i + 1] = pref[i] + len[i];
}
for (int qi = 0; qi < q; ++qi) {
ll x;
cin >> x;
ll ans;
if (x > pref.back()) {
ans = -1;
} else {
int block = int(lower_bound(pref.begin() + 1, pref.end(), x) - pref.begin()) - 1;
int j = block / 2;
if (block % 2 == 0) {
ans = a[j];
} else if (a[j] == a[j + 1]) {
ans = 0;
} else {
ll dir = (a[j + 1] > a[j] ? 1 : -1);
ll offset = x - pref[block];
ans = a[j] + dir * offset;
}
}
if (qi) cout << ' ';
cout << ans;
}
cout << '\n';
return 0;
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int n, q;
cin >> n >> q;
vector<ll> a(n);
for (ll &v : a) cin >> v;
vector<ll> len(2 * n - 1, 1);
for (int i = 0; i + 1 < n; ++i) {
if (a[i] != a[i + 1]) len[2 * i + 1] = llabs(a[i + 1] - a[i]) - 1;
}
vector<ll> pref(2 * n, 0);
for (int i = 0; i < (int)len.size(); ++i) {
pref[i + 1] = pref[i] + len[i];
}
for (int qi = 0; qi < q; ++qi) {
ll x;
cin >> x;
ll ans;
if (x > pref.back()) {
ans = -1;
} else {
int block = int(lower_bound(pref.begin() + 1, pref.end(), x) - pref.begin()) - 1;
int j = block / 2;
if (block % 2 == 0) {
ans = a[j];
} else if (a[j] == a[j + 1]) {
ans = 0;
} else {
ll dir = (a[j + 1] > a[j] ? 1 : -1);
ll offset = x - pref[block];
ans = a[j] + dir * offset;
}
}
if (qi) cout << ' ';
cout << ans;
}
cout << '\n';
return 0;
}