Ответ 1
Хитрость заключается в том, чтобы понять, что нам нужно всего лишь найти минимум j такой, что (A[0] + ... + A[j-1]) == (A[0] + ... + A[i]) - 1
. A[j] + ... + A[i]
совпадает с (A[0] + ... + A[i]) - (A[0] + ... + A[j-1])
, поэтому, как только мы найдем правильный j, сумма между j и я будет равна 1.
Любое раннее j не дало бы положительного значения, и любой последующий j не дал бы нам максимально возможной последовательности. Если мы будем отслеживать, где мы сначала достигаем каждого последующего отрицательного значения, то мы можем легко найти правильный j для любого заданного i.
Вот реализация С++:
vector<int> solve(const vector<int> &A)
{
int n = A.size();
int sum = 0;
int min = 0;
vector<int> low_points;
low_points.push_back(-1);
// low_points[0] is the position where we first reached a sum of 0
// which is just before the first index.
vector<int> B(n,-1);
for (int i=0; i!=n; ++i) {
sum += A[i];
if (sum<min) {
min = sum;
low_points.push_back(i);
// low_points[-sum] will be the index where the sum was first
// reached.
}
else if (sum>min) {
// Go back to where the sum was one less than what it is now,
// or go all the way back to the beginning if the sum is
// positive.
int index = sum<1 ? -(sum-1) : 0;
int length = i-low_points[index];
if (length>1) {
B[i] = length;
}
}
}
return B;
}