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>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define repd(i,a,b) for(int i=a;i>=b;--i)
#define rvc(i,S) for(int i=0;i<(int)S.size();++i)
#define fore(i,x) for(int i = head[x] ; i ; i = e[i].next)
#define mp make_pair
#define pb push_back
#define maxn 1000005
#define ll long long 
#define fi first
#define se second
#define debug(...) fprintf(stderr,__VA_ARGS__)
using namespace std;
const ll INF = 0x3f3f3f3f;
int n,m;
int vis[maxn];
int a[maxn],f[maxn][2],Max[maxn*4][2];
pair<int,int> query(int node,int l,int r,int lx,int rx)
{ if(lx>rx) return mp(0,0);
  if(lx<=l&&rx>=r) return mp(Max[node][0],Max[node][1]);
  pair<int,int> ans=mp(0,0);
  int mid=(l+r)>>1;
  if(lx<=mid) ans=query(node<<1,l,mid,lx,rx);
  if(rx>=mid+1)
    { pair<int,int> y=query(node<<1|1,mid+1,r,lx,rx);
      ans.fi=max(ans.fi,y.fi);
      ans.se=max(ans.se,y.se);
	}
return ans;
}
void add(int node,int l,int r,int pos,int id)
{ if(l==r)
   {Max[node][0]=f[id][0];Max[node][1]=f[id][1];
    return;
   }
   int mid=(l+r)>>1;
   if(pos<=mid) add(node<<1,l,mid,pos,id);
   else         add(node<<1|1,mid+1,r,pos,id);
   Max[node][0]=max(Max[node<<1][0],Max[node<<1|1][0]);
   Max[node][1]=max(Max[node<<1][1],Max[node<<1|1][1]);
}
bool check(int val,int lef)
{ if(lef<0) return 0;
  pair<int,int> y=query(1,1,n,val+1,n);
  if(!((y.fi-lef)&1)) return y.first>=lef;
  else                return y.se>=lef;
}
signed main()
{ cin>>n;
  rep(i,1,n) scanf("%d",&a[i]);
  for(int x=0,i=1;i<=n;i++)
  { x=max(x,a[i]);
    if(x==a[i])  ++vis[i];
  }
  repd(i,n,1) vis[i]+=vis[i+1];
  repd(i,n,1)
   { int t=1+(vis[i]!=vis[i+1]);//1 or 2
     pair<int,int> y=query(1,1,n,a[i]+1,n);
     f[i][(y.fi+t)&1]=max(f[i][(y.fi+t)&1],y.fi+t);
     f[i][(y.se+t)&1]=max(f[i][(y.se+t)&1],y.se+t);
     add(1,1,n,a[i],i);
   }
  if(!check(0,vis[1])) {puts("-1");return 0;}	
  int len[2]={0},pos[2]={0};
  rep(i,1,n)
  { f[i][0]=f[i][1]=0;
    add(1,1,n,a[i],i);
	int x=a[i]>a[pos[0]]?i:pos[0];
	int y=len[0]+(x==i);
	if(check(a[x],len[1]+vis[i+1]-y)||check(a[pos[1]],y+vis[i+1]-len[1])) 
	 {putchar('0');
	  len[0]=y;
	  pos[0]=x;
	 }
	else
	 {pos[1]=a[i]>a[pos[1]]?i:pos[1];
	  len[1]+=pos[1]==i;
      putchar('1');
	 }
  }
return 0;	
}