Problem:
Score : 600 points

Problem Statement

Snuke has an integer sequence A of length N.

He will make three cuts in A and divide it into four (non-empty) contiguous subsequences B, C, D and E.
The positions of the cuts can be freely chosen.

Let P,Q,R,S be the sums of the elements in B,C,D,E, respectively.
Snuke is happier when the absolute difference of the maximum and the minimum among P,Q,R,S is smaller.
Find the minimum possible absolute difference of the maximum and the minimum among P,Q,R,S.

Constraints

4 \leq N \leq 2 \times 10^5

1 \leq A_i \leq 10^9

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
A_1 A_2 ... A_N

Output

Find the minimum possible absolute difference of the maximum and the minimum among P,Q,R,S.

Sample Input 1

5
3 2 4 1 2

Sample Output 1

2

If we divide A as B,C,D,E=(3),(2),(4),(1,2), then P=3,Q=2,R=4,S=1+2=3.
Here, the maximum and the minimum among P,Q,R,S are 4 and 2, with the absolute difference of 2.
We cannot make the absolute difference of the maximum and the minimum less than 2, so the answer is 2.

Sample Input 2

10
10 71 84 33 6 47 23 25 52 64

Sample Output 2

36

Sample Input 3

7
1 2 3 1000000000 4 5 6

Sample Output 3

999999994

Solution in Haskell (GHC 7.10.3) (judge verdict: Time Limit Exceeded)

{-# LANGUAGE BangPatterns #-}
import Control.Arrow
import Control.Applicative
import Control.Monad.Fix
import Control.Monad.ST
import Data.Int
import Data.Foldable
import Data.List
import qualified Data.Vector as V
import qualified Data.Vector.Unboxed as VU
import qualified Data.ByteString.Char8 as B
import Debug.Trace

-- `binSearch p` searches for an integer `n` s.t. n = min {p k | k \in nat}
binSearch :: (Int -> Bool) -> Int
binSearch pred = if pred 0
  then 0
  else let k = findInterval pred in search (k `div` 2) k
 where
  findInterval pred = head $ dropWhile (not . pred) $ map (2 ^) [0 ..]

  -- (x,y]
  search x y
    | y - x == 1
    = y
    | otherwise
    = let z = (x + y) `div` 2 in if pred z then search x z else search z y

solve :: Int -> VU.Vector Int -> Int
solve !n !an = binSearch canSplitWithin
 where
  sum = VU.sum an

  isWithIn d acc =
    length acc == 4 && let acc' = sort acc in last acc' - head acc' <= d

  canSplitWithin d = isWithIn d $ (\(!x, _, _, _) -> x) $ fix
    (\(!f) (!acc, !cur, !i, !len) -> case () of
      () | i == VU.length an       -> (cur : acc, 0, i, 4)
      () | len == 3                -> f (acc, cur + an VU.! i, i + 1, len)
      () | cur + an VU.! i < thMin -> f (acc, cur + an VU.! i, i + 1, len)
      () | cur > thMax             -> ([], 0, 0, 0)
      () | otherwise ->
        let res1 =
              let result@(!acc', _, _, _) =
                    f ((cur + an VU.! i) : acc, 0, i + 1, len + 1)
              in  if isWithIn d acc' then Just result else Nothing
            res2 =
              let result@(!acc', _, _, _) =
                    f (acc, an VU.! i + cur, i + 1, len)
              in  if isWithIn d acc' then Just result else Nothing
        in  maybe ([], 0, 0, 0) id $ res1 <|> res2
    )
    ([], 0 :: Int, 0 :: Int, 0 :: Int)
   where
    thMin = ceiling (fromIntegral (sum - 3 * d) / 4)
    thMax = floor (fromIntegral (sum + 3 * d) / 4)

main = do
  let readInt :: Integral a => B.ByteString -> Maybe (a, B.ByteString)
      readInt = fmap (first fromIntegral . second B.tail) . B.readInt

  n  <- (\vec -> (vec VU.! 0)) . VU.unfoldrN 1 readInt <$> B.getLine
  an <- VU.unfoldrN n readInt <$> B.getLine
  print $ solve n an