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 Java8 (OpenJDK 1.8.0) (judge verdict: Wrong Answer)

import java.util.Arrays;
import java.util.Scanner;

public class Main
{
	static int maxn=200000+100;
	static int n;
	static node[]ns=new node[maxn];
	static int[]bit=new int[maxn];
	static int[]arr=new int[maxn];
	static Scanner scan=new Scanner(System.in);
	
	public static void main(String[] args)
	{
//		new Thread(new analyze()).start();
		read();
		System.out.println(cal());
	}
	
	//二分计算答案
	static long cal() {
		long l=0,r=4000000000L;//左开右闭
		long tot=(long)(n+1)*n/2;
		while(r-l>1) {
			long mid=(l+r)>>1;
			if(2*f(mid)>=tot)
				r=mid;
			else
				l=mid;
		}
		return r;	
	}
	
	//计算中位数小于等于x的区间个数
	static long f(long x) {
		ns[1]=new node(-1,1);
		for(int i=2;i<n+2;i++) {
			ns[i]=new node((arr[i-1]>x?1:-1)+ns[i-1].sum,i);
		}
		Arrays.sort(ns,1,n+2);
		//清空bit
		for(int i=1;i<maxn;i++)bit[i]=0;
		long ans=0;
		add(ns[n+1].pos);
		for(int i=n;i>=1;i--){
			ans+=que(ns[i].pos);
			add(ns[i].pos);
		}
		return ans;
	}
	
	//树状数组查询操作
	static int que(int x) {
		int ans=0;
		while(x>0) {
			ans+=bit[x];
			x-=x&-x;
		}
		return ans;
	}
	
	//树状数组更新操作
	static void add(int x) {
		while(x<maxn) {
			bit[x]++;
			x+=x&-x;
		}
	}
	
	//读入数据
	static void read() {
		n=scan.nextInt();
		for(int i=1;i<=n;i++) {
			arr[i]=scan.nextInt();
		}
	}
}
class node implements Comparable<node>{
	int sum;
	int pos;
	public node(int s,int p) {
		sum=s;pos=p;
	}
	@Override
	public int compareTo(node arg0)
	{
		return this.sum==arg0.sum?this.pos-arg0.pos:this.sum-arg0.sum;
	}
}