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.
A teleport set is judged by the closest friend-teleport pair. So instead of thinking about friends walking, think: every chosen teleport should be as far as possible from all friend positions.
For any integer position , its value is . The answer is simply the distinct positions with the largest values of . No hidden interaction between teleports besides being distinct. Nice, for once.
Sort the friend positions and remove duplicates. The line splits into independent regions: left of the first friend, right of the last friend, and gaps between consecutive friends.
Inside an edge region, distances are monotonic as you move away from the nearest friend. Inside a gap , distances peak near the midpoint, then decrease outward. For a target distance , you can count how many valid integer positions have without iterating over .
Binary search the maximum distance such that at least integer positions are distance at least from every friend. Output positions with distance first, then fill the remaining slots using positions with distance exactly .
We need maximize the time until the first friend reaches a teleport.
For chosen teleport positions , friend reaches the nearest teleport after
The first friend arrives after
That is just the minimum distance between any chosen teleport and any friend. So each teleport position has its own score:
We need choose the distinct integer positions in with the largest scores . There is no extra spacing condition between teleports. If two great spots are adjacent, take them both. The teleports are not allergic to each other.
Compress the friends
Duplicate friend positions do not change distances, so sort and erase duplicates.
Now look at the free integer positions by regions:
If the optimal distance is positive, friend positions are useless. But if everything else is exhausted, distance positions may be needed, so the implementation handles them too.
Counting positions with distance at least
Define = number of integer positions such that .
For , every position works, so .
For :
Left edge positions must be at most , so there are
positions.
Right edge positions must be at least , so there are
positions.
For a gap between consecutive friend positions and , a valid teleport must satisfy both:
and
So
That contributes
positions.
This gives an checker. Binary search the largest with .
Call this distance .
Building the actual answer
After binary search, every position with distance greater than is definitely in the top group. Positions with distance exactly are tied for the cutoff. So:
Instead of calculating one by one over the gigantic range, generate these positions region-by-region.
For a threshold , all positions with are exactly:
So we can have a helper add(D, strict):
strict = true, add positions with distance at least , i.e. distance ;strict = false, add positions with distance at least , skipping already-added positions.A set is used only while constructing the output to avoid duplicates between passes. Since we stop after positions and total over all tests is bounded, this is totally fine.
When , the second pass with threshold can simply fill remaining positions from friend positions or, more generally, from while skipping already used positions. Since , this loop stops quickly. No billion-step nonsense.
Correctness proof
Let be the distance from position to the nearest friend.
First, for any chosen teleport set , the objective value is
This equals
because is already the nearest-friend distance for teleport position . Therefore the quality of a teleport set is the minimum score among its chosen positions.
So an optimal solution is obtained by choosing the positions with largest values. If the -th largest distance is , then every chosen position must have distance at least , and there must be at least positions with distance at least .
The counting formula for is exact because sorted friend positions partition the line into edge regions and gaps. On each edge, only one nearest friend can constrain the distance. In each middle gap , the nearest friend is one of the two endpoints, so a point is distance at least from all friends exactly when it is at least away from both and , giving .
Thus is exactly the number of positions whose score is at least . Since is non-increasing as grows, binary search finds the maximum feasible distance with .
All positions with distance greater than must be selected before any position with smaller distance. Since is maximal feasible, fewer than positions have distance greater than . The construction first outputs all available positions with distance greater than , then fills with positions of distance at least kk$ distinct positions are output.
So the minimum friend-teleport distance of the constructed set is optimal.
Complexity
For each test case, sorting costs .
The binary search runs checks, each .
Construction outputs at most positions plus scans the gaps, so it is .
Overall:
per test case, easily inside the limits.
#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 T;
cin >> T;
while (T--) {
int n, k;
ll x;
cin >> n >> k >> x;
vector<ll> a(n);
for (ll &v : a) cin >> v;
sort(a.begin(), a.end());
a.erase(unique(a.begin(), a.end()), a.end());
auto count_ge = [&](ll d) -> ll {
if (d == 0) return x + 1;
ll cnt = 0;
if (a[0] >= d) cnt += a[0] - d + 1;
if (a.back() + d <= x) cnt += x - (a.back() + d) + 1;
for (int i = 0; i + 1 < (int)a.size(); i++) {
ll L = a[i], R = a[i + 1];
if (L + d <= R - d) cnt += (R - d) - (L + d) + 1;
}
return min<ll>(cnt, k);
};
ll lo = 0, hi = x;
while (lo < hi) {
ll mid = (lo + hi + 1) / 2;
if (count_ge(mid) >= k) lo = mid;
else hi = mid - 1;
}
ll best = lo;
vector<ll> ans;
unordered_set<ll> used;
used.reserve(2 * k + 10);
auto push = [&](ll p) {
if ((int)ans.size() == k) return;
if (p < 0 || p > x) return;
if (used.insert(p).second) ans.push_back(p);
};
auto add_range = [&](ll l, ll r) {
if (l > r) return;
for (ll p = l; p <= r && (int)ans.size() < k; p++) push(p);
};
auto add_ge = [&](ll d) {
if ((int)ans.size() == k) return;
if (d == 0) {
add_range(0, x);
return;
}
add_range(0, a[0] - d);
for (int i = 0; i + 1 < (int)a.size() && (int)ans.size() < k; i++) {
add_range(a[i] + d, a[i + 1] - d);
}
add_range(a.back() + d, x);
};
add_ge(best + 1);
add_ge(best);
for (int i = 0; i < k; i++) {
if (i) cout << ' ';
cout << ans[i];
}
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 T;
cin >> T;
while (T--) {
int n, k;
ll x;
cin >> n >> k >> x;
vector<ll> a(n);
for (ll &v : a) cin >> v;
sort(a.begin(), a.end());
a.erase(unique(a.begin(), a.end()), a.end());
auto count_ge = [&](ll d) -> ll {
if (d == 0) return x + 1;
ll cnt = 0;
if (a[0] >= d) cnt += a[0] - d + 1;
if (a.back() + d <= x) cnt += x - (a.back() + d) + 1;
for (int i = 0; i + 1 < (int)a.size(); i++) {
ll L = a[i], R = a[i + 1];
if (L + d <= R - d) cnt += (R - d) - (L + d) + 1;
}
return min<ll>(cnt, k);
};
ll lo = 0, hi = x;
while (lo < hi) {
ll mid = (lo + hi + 1) / 2;
if (count_ge(mid) >= k) lo = mid;
else hi = mid - 1;
}
ll best = lo;
vector<ll> ans;
unordered_set<ll> used;
used.reserve(2 * k + 10);
auto push = [&](ll p) {
if ((int)ans.size() == k) return;
if (p < 0 || p > x) return;
if (used.insert(p).second) ans.push_back(p);
};
auto add_range = [&](ll l, ll r) {
if (l > r) return;
for (ll p = l; p <= r && (int)ans.size() < k; p++) push(p);
};
auto add_ge = [&](ll d) {
if ((int)ans.size() == k) return;
if (d == 0) {
add_range(0, x);
return;
}
add_range(0, a[0] - d);
for (int i = 0; i + 1 < (int)a.size() && (int)ans.size() < k; i++) {
add_range(a[i] + d, a[i + 1] - d);
}
add_range(a.back() + d, x);
};
add_ge(best + 1);
add_ge(best);
for (int i = 0; i < k; i++) {
if (i) cout << ' ';
cout << ans[i];
}
cout << '\n';
}
return 0;
}