§ Parallelisable version of maximum sum subarray
I learnt of a "prefix sum/min" based formulation from
the solution to question D, codeforces educational round 88 .
The idea is to start with the max prefix sum opt (for optima)
as the difference of right minus
left:
opt≡(L,R)max:L≤i≤R∑a[i]=Rmax:(0≤i≤R∑a[i]−L≤Rmin:0≤i≤L≤R∑a[i])
Which is then expressed as:
asum[n]≡0≤i≤n∑a[i]opt=Rmax:(asum[R]−(L≤R)min:asum[L])
aminsum[n]≡0≤i≤nminasum[i]opt=Rmax:(asum[R]−aminsum[R])
Since asum is a prefix-sum of a, and amin is a prefix min of
asum, the whole thing is O(n) serial, O(logn) parallel.
In haskell, this translates to:
let heights deltas = scanl (+) 0 deltas
let lowest_heights = scanl1 min . sums
let elevations xs = zipWith (-) (sums xs) (lowest_heights xs)
let max_elevation deltas = max (elevation deltas)
best = max_elevations [1, 2, 3, -2, -1, -4, 4, 6]
lowest_heights
keeps track of the sea level, while the
elevations
computes the elevation from the lowest height.
The maximum sum subarray will correspond to treating the elements of the array
as deltas, where we are trying to find the highest elevation. since elevation
is an integral (sum) of the deltas in height.