Problem:
Score : 1400 points

Problem Statement

You are given P, a permutation of (1,\ 2,\ ...\ N).

A string S of length N consisting of 0 and 1 is a good string when it meets the following criterion:

The sequences X and Y are constructed as follows:

First, let X and Y be empty sequences.

For each i=1,\ 2,\ ...\ N, in this order, append P_i to the end of X if S_i= 0, and append it to the end of Y if S_i= 1.

If X and Y have the same number of high elements, S is a good string.
Here, the i-th element of a sequence is called high when that element is the largest among the elements from the 1-st to i-th element in the sequence.

Determine if there exists a good string. If it exists, find the lexicographically smallest such string.

Constraints

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

1 \leq P_i \leq N

P_1,\ P_2,\ ...\ P_N are all distinct.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
P_1 P_2 ... P_N

Output

If a good string does not exist, print -1.
If it exists, print the lexicographically smallest such string.

Sample Input 1

6
3 1 4 6 2 5

Sample Output 1

001001

Let S= 001001. Then, X=(3,\ 1,\ 6,\ 2) and Y=(4,\ 5).
The high elements in X is the first and third elements, and the high elements in Y is the first and second elements.
As they have the same number of high elements, 001001 is a good string.
There is no good string that is lexicographically smaller than this, so the answer is 001001.

Sample Input 2

5
1 2 3 4 5

Sample Output 2

-1

Sample Input 3

7
1 3 2 5 6 4 7

Sample Output 3

0001101

Sample Input 4

30
1 2 6 3 5 7 9 8 11 12 10 13 16 23 15 18 14 24 22 26 19 21 28 17 4 27 29 25 20 30

Sample Output 4

000000000001100101010010011101

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include<bits/stdc++.h>
using namespace std;

int read(){
	int a = 0; char c = getchar();
	while(!isdigit(c)) c = getchar();
	while(isdigit(c)){
		a = a * 10 + c - 48; c = getchar();
	}
	return a;
}

const int _ = 2e5 + 7;
int val[_] , cnt[_] , N;

bool cmp(int a , int b){return a > b;}

struct segTree{
	int mx[_ << 2];

	void init(){memset(mx , -0x3f , sizeof(mx));}

#define mid ((l + r) >> 1)
#define lch (x << 1)
#define rch (x << 1 | 1)

	void modify(int x , int l , int r , int tar , int val){
		if(l == r){mx[x] = val; return;}
		mid >= tar ? modify(lch , l , mid , tar , val) : modify(rch , mid + 1 , r , tar , val);
		mx[x] = max(mx[lch] , mx[rch]);
	}

	int qry(int x,  int l , int r , int L , int R){
		if(l >= L && r <= R) return mx[x];
		int Mx = -1e9;
		if(mid >= L) Mx = qry(lch , l , mid , L , R);
		if(mid < R) Mx = max(Mx , qry(rch , mid + 1 , r , L , R));
		return Mx;
	}
}T1 , T2;

bool check(int pos , int Mx1 , int Mx2 , int cnt1 , int cnt2){
	int V1 = cnt1 + cnt[pos] - cnt2 , V2 = cnt2 + cnt[pos] - cnt1;
	if(V1 >= 0)
		if(V1 & 1){if(T1.qry(1 , 1 , N , Mx2 , N) >= V1) return 1;}
		else if(T2.qry(1 , 1 , N , Mx2 , N) >= V1) return 1;
	if(V2 >= 0)
		if(V2 & 1){if(T1.qry(1 , 1 , N , Mx1 , N) >= V2) return 1;}
		else if(T2.qry(1 , 1 , N , Mx1 , N) >= V2) return 1;
	return 0;
}

int main(){
	N = read();
	int pre = 0;
	for(int i = 1 ; i <= N ; ++i){
		val[i] = read(); cnt[i] = val[i] > pre;
		pre = max(pre , val[i]);
	}
	for(int i = N ; i ; --i) cnt[i] += cnt[i + 1];
	T1.init();
	for(int i = N ; i ; --i){
		int p0 = T1.qry(1 , 1 , N , val[i] , N) , p1 = T2.qry(1 , 1 , N , val[i] , N);
		if(cnt[i] > cnt[i + 1]){
			T1.modify(1 , 1 , N , val[i] , p0 + 2);
			T2.modify(1 , 1 , N , val[i] , p1 + 2);
		}
		else{
			T1.modify(1 , 1 , N , val[i] , p1 + 1);
			T2.modify(1 , 1 , N , val[i] , p0 + 1);
		}
	}
	vector < int > arr1 , arr2; string s;
	int Mx1 = 1 , Mx2 = 1 , cnt1 = 0 , cnt2 = 0;
	for(int i = 1 ; i <= N ; ++i){
		T1.modify(1 , 1 , N , val[i] , -1e9);
		T2.modify(1 , 1 , N , val[i] , 0);
		if(check(i + 1 , max(Mx1 , val[i]) , Mx2 , cnt1 + (Mx1 <= val[i]) , cnt2)){
			arr1.push_back(val[i]); cnt1 += Mx1 <= val[i]; Mx1 = max(Mx1 , val[i]);
			s.push_back('0');
		}
		else{
			arr2.push_back(val[i]); cnt2 += Mx2 <= val[i]; Mx2 = max(Mx2 , val[i]);
			s.push_back('1');
		}
	}
	if(cnt1 == cnt2) cout << s;
	else cout << -1;
	return 0;
}