Calculate The Medians
Difficulty: Hard

<sub>*Time limits* for this challenges is two times of the [default one](https://www.hackerrank.com/environment).</sub>

The math teacher loves the concept of median very much. One day, he comes up with a question about medians and wants the students to solve it.

He provides his students with two arrays of integers, 

- $A = \{a_1, a_2, \ldots, a_n\}$
- $B = \{b_1, b_2, \ldots, b_m\}$  

, followed by $k$ queries.  
Each query consists of two ranges, $(x, y)$ and $(z, w)$ for both arrays, respectively. The students need to compute the median of a new array formed by concatenating subarrays $A[x \ldots y] = \{a_x, a_{x+1}, ... , a_y\}$ and $B[z \ldots w] = \{b_z, b_{z+1}, ... , b_w\}$.

Could you solve it by writing a computer program?

*Note*

- Indexing starts from 1.
- Median of a sorted array with
	- an odd number of elements is the middle integer.
	- an even number of elements is the average of two middle integers.

Input Format:
The first line contains two integers, $n$ and $m$, indicating lengths of the two arrays $A$ and $B$, respectively.<br>
The second line contains $n$ integers, representing the array $A$.<br>
The third line contains $m$ integers, representing the array $B$.<br>
The fourth line contains an integer $k$, indicating the number of queries.<br>
Then follows $k$ lines, each line contains four integers $x$, $y$, $z$ and $w$, as described above.

Output Format:
For each query, output the answer in a single line. 

**Constraints**

- $1 \le n, m \le 50000$
- $1 \le a_i, b_j \le 10^9\ , i \in [1, n], j \in [1, m]$
- $1 \le k \le 20000$
- $1 \le x \le y \le n$
- $1 \le z \le w \le m$
- The absolute error between your and expected output should not exceed $10^{-6}$.

Sample Input:
    5 6
    4 3 9 7 8
    1 8 3 6 5 2
    4
    1 5 1 6
    1 1 2 4
    1 2 3 4
    3 5 4 6

Sample Output:
    5.0
    5.0
    3.5
    6.5

Python 3 starter code:


Reference solution (Python):
**Solution with partition trees**

	import Control.Applicative
	import Control.Monad
	import Data.Int
	import Data.List
	import qualified Data.Vector as V
	import Text.Printf
	
	data Tree = Node (V.Vector Int32) Tree Tree
	          | Leaf Int32
	
	type Struct = (Tree, V.Vector Int32)
	
	buildStruct :: [Int32] -> Struct
	buildStruct xs = (tree, vs)
	  where
	  vs = V.fromList . sort $ xs
	  n  = fromIntegral $! V.length vs
	  tree = innerBuild 0 (n - 1) xs
	  innerBuild a b xs
	    | a == b    = Leaf a
	    | otherwise = Node toLeft ch0 ch1
	      where
	      mid = (a + b) `div` 2
	      ch0 = innerBuild a mid lxs
	      ch1 = innerBuild (mid + 1) b rxs
	      toLeft = V.fromList $! reverse $! toLeftRev
	      (lxs, rxs, toLeftRev) = getLeft xs []
	      getLeft [] ll = ([], [], ll)
	      getLeft (x:xs) ll = (ls, rs, rll)
	        where
	        i = case ll of
	          []      -> 0
	          x:ll    -> x
	        half = mid + 1 - a
	        midX = vs V.! fromIntegral mid
	        flag = x < midX || i < half && x == midX
	        (ls', rs', rll) =
	          if flag
	            then getLeft xs ((i+1):ll)
	            else getLeft xs (i:ll)
	        ls = if flag then x:ls' else ls'
	        rs = if flag then rs' else x:rs'

	queryStruct :: Struct -> Int32 -> Int32 -> Int32 -> Int32
	queryStruct (tree,vs) x y k = query tree x y k
	  where
	  query (Leaf a) _ _ k = vs V.! fromIntegral a
	  query (Node toLeft ch0 ch1) x y k = result
	    where
	    lx = if x > 0 then toLeft V.! fromIntegral (x-1) else 0
	    ly = toLeft V.! fromIntegral y
	    result =
	      if lx + k > ly
	        then query ch1 (x - lx) (y - ly) (k - (ly - lx))
	        else query ch0 lx (ly - 1) k
	
	oo = 2 * 10 ^ 9
	
	queryMedian :: Struct -> Struct -> Int32 -> Int32 -> Int32 -> Int32 -> Double
	queryMedian s1 s2 x y z w = fromIntegral (r1 + r2) / 2.0
	  where
	  tot = y - x + 1 + w - z + 1
	  p = (tot + 1) `div` 2
	  getKth s x y k
	    | k == 0          = 0
	    | k > y - x + 1   = oo
	    | otherwise       = queryStruct s x y k
	  i = bin 0 (min (y - x + 2) (p + 1))
	  j = p - i
	  bin l r = if l + 1 == r then l
	    else if getKth s1 x y mid <= getKth s2 z w (p - mid + 1)
	      then bin mid r else bin l mid
	        where
	        mid = (l + r) `div` 2
	  r1 = max (getKth s1 x y i) (getKth s2 z w j)
	  r2 = if tot `mod` 2 == 1 then r1
	    else min (getKth s1 x y (i + 1)) (getKth s2 z w (j + 1))

	solveQuery :: Struct -> Struct -> [[Int32]] -> IO ()
	solveQuery s1 s2 qs = innerSolve qs
	  where
	  innerSolve :: [[Int32]] -> IO ()
	  innerSolve []             = return ()
	  innerSolve ([x,y,z,w]:qs) = do
	    printf "%.1f\n" $! queryMedian s1 s2 (x-1) (y-1) (z-1) (w-1)
	    innerSolve qs
	
	main = do
	  getLine
	  xs <- map read . words <$> getLine
	  ys <- map read . words <$> getLine
	  getLine
	  qs <- map (map read . words) . lines <$> getContents
	  let s1 = buildStruct xs
	      s2 = buildStruct ys
	  solveQuery s1 s2 qs
      
**Solution with segment trees**

	import Control.Applicative
	import Control.Monad
	import Data.List
	import qualified Data.Vector as V
	import Text.Printf
	
	data Tree = Node Int Int Int Tree Tree
	          | Leaf Int Int
	
	initTree :: V.Vector Int -> Tree
	initTree vs = build 0 (n - 1)
	  where
	  n = V.length vs
	  build a b
	    | a == b    = Leaf (vs V.! a) 0
	    | otherwise = Node (vs V.! a) (vs V.! b) 0 lt rt
	      where
	      mid = (a + b) `div` 2
	      lt = build a mid
	      rt = build (mid + 1) b
	
	insertNum :: Tree -> Int -> Tree
	insertNum tree x = inner tree
	  where
	  inner leaf@(Leaf a cc) = if a == x then Leaf x (cc + 1) else leaf
	  inner node@(Node a b cc lt rt)
	    | a <= x && x <= b  = Node a b (cc + 1) (inner lt) (inner rt)
	    | otherwise         = node

	buildTrees :: [Int] -> Tree -> V.Vector Tree
	buildTrees xs init = V.fromList $! inner xs init []
	  where
	  inner [] t ts = reverse (t:ts)
	  inner (x:xs) t ts = inner xs (insertNum t x) (t:ts)
	
	queryKth :: Tree -> Tree -> Tree -> Tree -> Int -> Double
	queryKth (Leaf x _) _ _ _ _ = fromIntegral x
	queryKth (Node _ _ _ ly ry) (Node _ _ _ lx rx)
	         (Node _ _ _ lw rw) (Node _ _ _ lz rz) k =
	  if k <= th
	    then queryKth ly lx lw lz k
	    else queryKth ry rx rw rz $! k - th
	      where
	      th = getCC ly - getCC lx + getCC lw - getCC lz
	      getCC (Leaf _ cc) = cc
	      getCC (Node _ _ cc _ _) = cc
	
	solveQuery :: V.Vector Tree -> V.Vector Tree -> [[Int]] -> IO ()
	solveQuery ts1 ts2 qs = innerSolve qs
	  where
	  innerSolve :: [[Int]] -> IO ()
	  innerSolve []             = return ()
	  innerSolve ([x,y,z,w]:qs) = do
	    let n   = y - x + w - z + 2
	        m   = (n + 1) `div` 2
	        qk  = queryKth (ts1 V.! y) (ts1 V.! (x - 1))
	                       (ts2 V.! w) (ts2 V.! (z - 1))
	        r1  = qk m
	        r2  = if n `mod` 2 == 1 then r1 else qk (m + 1)
	    printf "%.1f\n" $! (r1 + r2) / 2.0
	    innerSolve qs
	
	main = do
	  contents <- lines <$> getContents
	  let xs  = map read . words $! contents !! 1
	      ys  = map read . words $! contents !! 2
	      vs  = V.fromList $! map head $! group $! sort $! xs ++ ys
	      it  = initTree vs
	      ts1 = buildTrees xs it
	      ts2 = buildTrees ys it
	      qs  = map (map read . words) $! drop 4 contents
	  solveQuery ts1 ts2 qs