The @chux clause is essentially a redistribution of operations:
a i * a i + 1 + a i * a i + 2 + ... + a i * a n
->
a i * (a i + 1 + ... + a n )
combined to avoid unnecessary recalculation of partial sums (a i + 1 + ... + a n ) of terms, using the fact that each is different from the next in the value of one element of the input array.
Here's a one-pass implementation with O (1) overhead:
int psum(size_t n, int array[n]) { int result = 0; int rsum = array[n - 1]; for (int i = n - 2; i >= 0; i--) { result += array[i] * rsum; rsum += array[i]; } return result; }
The sum of all elements to the right of index i supported from iteration to iteration in the rsum variable. There is no need to track its various values ββin the array, because we need each value for only one iteration of the loop.
This scales linearly with the number of elements in the input array. You will see that the number and type of operations are very similar to @Barry's answer, but nothing similar to his last step is required, which saves a few operations.
As @Barry notes in the comments, iteration can also be performed in a different direction, combined with tracking left partial sums taking into account right ones. This will differ from the @chux description, but it is based on the same principles.
source share