Problem:
Score : 700 points

Problem Statement

We will define the median of a sequence b of length M, as follows:

Let b' be the sequence obtained by sorting b in non-decreasing order. Then, the value of the (M / 2 + 1)-th element of b' is the median of b. Here, / is integer division, rounding down.

For example, the median of (10, 30, 20) is 20; the median of (10, 30, 20, 40) is 30; the median of (10, 10, 10, 20, 30) is 10.

Snuke comes up with the following problem.

You are given a sequence a of length N.
For each pair (l, r) (1 \leq l \leq r \leq N), let m_{l, r} be the median of the contiguous subsequence (a_l, a_{l + 1}, ..., a_r) of a.
We will list m_{l, r} for all pairs (l, r) to create a new sequence m.
Find the median of m.

Constraints

1 \leq N \leq 10^5

a_i is an integer.

1 \leq a_i \leq 10^9

Input

Input is given from Standard Input in the following format:

N
a_1 a_2 ... a_N

Output

Print the median of m.

Sample Input 1

3
10 30 20

Sample Output 1

30

The median of each contiguous subsequence of a is as follows:

The median of (10) is 10.

The median of (30) is 30.

The median of (20) is 20.

The median of (10, 30) is 30.

The median of (30, 20) is 30.

The median of (10, 30, 20) is 20.

Thus, m = (10, 30, 20, 30, 30, 20) and the median of m is 30.

Sample Input 2

1
10

Sample Output 2

10

Sample Input 3

10
5 9 5 9 8 9 3 5 4 3

Sample Output 3

8

Solution in LuaJIT (2.0.4) (judge verdict: Accepted)

local mfl, mce, mmi = math.floor, math.ceil, math.min
local mma = math.max
local SegTree = {}
SegTree.updateAll = function(self)
  for i = self.stagenum - 1, 1, -1 do
    for j = 1, self.cnt[i] do
      self.stage[i][j] = self.stage[i + 1][j * 2 - 1] + self.stage[i + 1][j * 2]
    end
  end
end
SegTree.clear = function(self)
  for i = self.stagenum, 1, -1 do
    for j = 1, self.cnt[i] do
      self.stage[i][j] = 0
    end
  end
end
SegTree.create = function(self, n)
  local stagenum, mul = 1, 1
  self.cnt, self.stage, self.size = {1}, {{}}, {}
  while mul < n do
    mul, stagenum = mul * 2, stagenum + 1
    self.cnt[stagenum], self.stage[stagenum] = mul, {}
  end
  for i = 1, stagenum do self.size[i] = self.cnt[stagenum + 1 - i] end
  self.stagenum = stagenum
  self:clear()
end
SegTree.getRange = function(self, right)
  local stage = 1
  while right < self.size[stage] do
    stage = stage + 1
  end
  local ret = 0
  local l, r = 1, right
  while true do
    local sz = self.size[stage]
    ret = ret + self.stage[stage][mce(l / sz)]
    l = l + sz
    if l <= r then
      local nsize = r + 1 - l
      while nsize < self.size[stage] do
        stage = stage + 1
      end
    else
      break
    end
  end
  return ret
end
SegTree.inc = function(self, idx)
  self.stage[self.stagenum][idx] = self.stage[self.stagenum][idx] + 1
end
SegTree.dec = function(self, idx)
  self.stage[self.stagenum][idx] = self.stage[self.stagenum][idx] - 1
  for i = self.stagenum - 1, 1, -1 do
    local dst = mce(idx / 2)
    local rem = dst * 4 - 1 - idx
    self.stage[i][dst] = self.stage[i + 1][idx] + self.stage[i + 1][rem]
    idx = dst
  end
end
SegTree.new = function(n)
  local obj = {}
  setmetatable(obj, {__index = SegTree})
  obj:create(n)
  return obj
end

local n = io.read("*n")
local a = {}
local t = {}
for i = 1, n do
  a[i] = io.read("*n")
  t[i] = a[i]
end
table.sort(t)
local totcnt = mfl(n * (n + 1) / 2)
local st = SegTree.new(n * 2 + 1)
local z = {}
local function solve(v)
  st:clear()
  local ofst = n + 1
  z[1] = v <= a[1] and 1 or -1
  for i = 2, n do
    z[i] = v <= a[i] and z[i - 1] + 1 or z[i - 1] - 1
  end
  for i = 1, n do
    st:inc(z[i] + ofst)
  end
  st:updateAll()
  local cnt = 0
  local n2_1 = 2 * n + 1
  for i = 1, n do
    local left = i == 1 and ofst or z[i - 1] + ofst
    if left <= 1 then
      cnt = cnt + n + 1 - i
    else
      cnt = cnt + n + 1 - i - st:getRange(left - 1)
    end
    st:dec(z[i] + ofst)
  end
  return totcnt <= cnt * 2
end
local function solveAll()
  if solve(t[n]) then
    return t[n]
  end
  local min, max = 1, n
  while 1 < max - min do
    local mid = mfl((min + max) / 2)
    if solve(t[mid]) then
      min = mid
    else
      max = mid
    end
  end
  return t[min]
end
print(solveAll())