I am working on the following task:
You are given a sorted collection of springs. Each of them has been produced in certain dimensions, and each stretching, or compression, requires quite a bit of effort. It takes 1 unit of effort to lengthen or shorten a spring that has not yet been moved by a centimeter. Each successive stretch, or compression, of the same spring requires an additional 1 unit of effort. More precisely, if you want to lengthen a spring by D centimeters, he will exert himself by 1,2,…,D successive units of effort.
Your task is to answer q queries about how much minimal effort it would cost to set the k-shortest springs to the same length.
Constraints: N,Q <= 106, xi <= 109
Input:
N, Q
x1, x2, x3, ...
q1, q2, q3, ...
N - number of springs
xi - length of i-th spring (Note that xi <= xi+1)
qi - how many springs should be set to the same length in i-th question
Output: Answers to questions - minimal effort it would cost to set the k-shortest springs to the same length. Because answer may be large print it modulo 10^9+7.
My solution attempt: I discovered that the minimal effort would be achieved when the springs are set to the average length of the springs. However in this approach complexity of algorithm is O(n*q) which is too slow for given constraints.
How can I solve this faster?
In my brutal approach I calculate the average length of the springs and then linearly calculate the cost for every spring. It is too slow for N,Q <= 106 but is enough for n,q <= 103.
The total effort for a spring with starting length x and target length v is proportional to (x-v)2.
For a bunch of N springs, Sum[(xi-v)2] = Sum[xi2] - 2v*Sum[xi] +Nv2
Note that the summations do not depend on the target length at all, so you can just precalculate Sum[xi2] and Sum[xi] for all the prefixes of your array in O(n) time.
Then for each query, you can look up the appropriate sums and calculate the minimum cost for any v in O(1) time, giving O(n+q) all together.
As you have already determined, the minimum effort target length is the average spring length Sum[xi]/N. That's not always going to be an integer, so just try the 2 integers on either side of it.