public:
long long putMarbles(vector<int>& weights, int k) {
int n = weights.size();
// pairs. Each pair's second value is the partition's index. The partition is to the right of the index.
// Each pair's first value is the sum of the two numbers to the left and right of the partition.
// So a pair would be {weights[ii] + weights[ii+1], ii}
vector<vector<int>> sumAndPIndexes{};
for(int ii=0; ii<n-1; ++ii)
{
sumAndPIndexes.push_back({weights[ii]+weights[ii+1], ii});
}
// The pairs are sorted in increasing order per each pair's first value. The first value is the partition's sum.
sort(sumAndPIndexes.begin(), sumAndPIndexes.end());
// the k-1 partitions that have the largest sums. The sum is the weight at the two indexes to the left and right of the partition.
// find these at the right end of the sorted sumAndPIndexes.
vector<int> partitionIndexesForMaximumScore{};
int idx = sumAndPIndexes.size()-1;
for (int ii=0; ii<k-1; ++ii)
{
partitionIndexesForMaximumScore.push_back(sumAndPIndexes[idx][1]);
--idx;
}
// the k-1 partitions that have the smallest sums.
// find these at the left end of the sorted sumAndPIndexes.
vector<int> partitionIndexesForMinimumScore{};
idx = 0;
for (int ii=0; ii<k-1; ++ii)
{
partitionIndexesForMinimumScore.push_back(sumAndPIndexes[idx][1]);
++idx;
}
// maxSum is the sum over the top k-1 partitions plus the weight at weight[0] and weight[n-1]
long long maxSum = weights[0];
maxSum += weights[n-1];
for(int ii=0; ii<partitionIndexesForMaximumScore.size(); ++ii)
{
int partitionIndex = partitionIndexesForMaximumScore[ii];
maxSum += weights[partitionIndex];
maxSum += weights[partitionIndex+1];
}
// minSum is the sum over the bottom k-1 partitions plus the weight at weight[0] and weight[n-1]
long long minSum = weights[0];
minSum += weights[n-1];
for(int ii=0; ii<partitionIndexesForMinimumScore.size(); ++ii)
{
int partitionIndex = partitionIndexesForMinimumScore[ii];
minSum += weights[partitionIndex];
minSum += weights[partitionIndex+1];
}
return std::abs(maxSum - minSum);
}
};