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.
Don’t get distracted by the whole difference array. Write out for a tiny array and see what cancels.
The sum telescopes: . So the objective only depends on the first and last elements. Interior blanks are basically emotional support variables.
To minimize , only consider whether and/or are fixed. If one endpoint is blank and the other is fixed, copy the fixed value into the blank endpoint.
If both endpoints are blank, the minimum is , and lexicographic order tells you to make as small as possible: . Then must also be .
After fixing the endpoints optimally, every remaining blank should be for lexicographic minimality, because interior values do not affect the answer at all.
The key thing is that the scary-looking expression is a total scam.
We are asked to minimize
where
Now expand the sum:
Everything in the middle cancels. We get
So the whole problem is just:
The middle elements have absolutely no effect on the value. They only matter for lexicographic smallest output.
Endpoint Cases
Only and affect the minimum.
If both are fixed, then the answer is forced:
No choice can change it.
If exactly one endpoint is blank, set it equal to the fixed endpoint. Then
which is obviously the best possible value.
If both endpoints are blank, set both equal. The minimum is again . For lexicographic smallest order, choose the smallest nonnegative value for , which is . Then must also be .
What About The Middle?
After the endpoints are handled, every blank middle element should be .
Why? Because middle elements do not affect the objective, and lexicographic order rewards smaller earlier values. Since values must be nonnegative, is always best. No fancy DP, no hidden trap, no quadratic nonsense. Just fill the dead weight with zeroes.
Algorithm
Correctness Proof
Let the final filled array be .
By telescoping,
Therefore the objective value is exactly , and no interior element can affect it.
If both endpoints are fixed, every valid filled array has the same endpoint values, so the minimum is forced.
If at least one endpoint is blank, we can make the two endpoints equal by assigning the blank endpoint appropriately. Since absolute values are always nonnegative, achieving is optimal.
Among all optimal arrays, the construction chooses the smallest possible value at the first endpoint whenever it is free. Then, for every remaining blank interior position, it chooses , the smallest allowed value. These positions do not affect optimality, so choosing greedily at each such position gives the lexicographically smallest optimal array.
Thus the algorithm outputs both the minimum possible value and the lexicographically smallest array achieving it.
Complexity
Each test case is processed in time and uses memory for the array. Across all test cases, this is , which easily fits.
#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;
cin >> n;
vector<ll> a(n);
for (ll &x : a) cin >> x;
if (a[0] == -1 && a[n - 1] == -1) {
a[0] = a[n - 1] = 0;
} else if (a[0] == -1) {
a[0] = a[n - 1];
} else if (a[n - 1] == -1) {
a[n - 1] = a[0];
}
for (ll &x : a) {
if (x == -1) x = 0;
}
cout << llabs(a[n - 1] - a[0]) << '\n';
for (int i = 0; i < n; i++) {
if (i) cout << ' ';
cout << a[i];
}
cout << '\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 t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<ll> a(n);
for (ll &x : a) cin >> x;
if (a[0] == -1 && a[n - 1] == -1) {
a[0] = a[n - 1] = 0;
} else if (a[0] == -1) {
a[0] = a[n - 1];
} else if (a[n - 1] == -1) {
a[n - 1] = a[0];
}
for (ll &x : a) {
if (x == -1) x = 0;
}
cout << llabs(a[n - 1] - a[0]) << '\n';
for (int i = 0; i < n; i++) {
if (i) cout << ' ';
cout << a[i];
}
cout << '\n';
}
}