The next "Data Structures and Algorithms" lesson will be about Longest Increasing Subsequence (LIS for short) of a sequence. For better understanding, Nam decided to learn it a few days before the lesson.
Nam created a sequence a consisting of n (1 ≤ n ≤ 105) elements a1, a2, ..., an (1 ≤ ai ≤ 105). A subsequence ai1, ai2, ..., aik where 1 ≤ i1 < i2 < ... < ik ≤ n is called increasing if ai1 < ai2 < ai3 < ... < aik. An increasing subsequence is called longest if it has maximum length among all increasing subsequences.
Nam realizes that a sequence may have several longest increasing subsequences. Hence, he divides all indexes i (1 ≤ i ≤ n), into three groups:
- group of all i such that ai belongs to no longest increasing subsequences.
- group of all i such that ai belongs to at least one but not every longest increasing subsequence.
- group of all i such that ai belongs to every longest increasing subsequence.
Since the number of longest increasing subsequences of a may be very large, categorizing process is very difficult. Your task is to help him finish this job.
The first line contains the single integer n (1 ≤ n ≤ 105) denoting the number of elements of sequence a.
The second line contains n space-separated integers a1, a2, ..., an (1 ≤ ai ≤ 105).
Print a string consisting of n characters. i-th character should be '1', '2' or '3' depending on which group among listed above index ibelongs to.
#include<cstdio>
#include<cstring>
int a[100100],f[100100],e[100100],g[100100],h[100100],ans[100100];
int find_mid(int l,int r, int a)
{
int mid;
if (r-l<2) return l;
mid=(l+r)/2;
if (h[mid]>a) return find_mid(l,mid,a);
else return find_mid(mid,r,a);
}
int main()
{
int i,k,n,mid,maxx;
scanf("%d", &n);
for (i=1;i<=n;i++) ans[i]=1;
memset(g,0,sizeof(g));
memset(f,0,sizeof(f));
memset(e,0,sizeof(e));
for (i=1;i<=n;i++) scanf("%d", &a[i]);
k=1;f[1]=1;h[1]=a[1];
for (i=2;i<=n;i++)
if (a[i]>h[k]) {
k++;f[i]=k;
h[k]=a[i];
} else {
if (a[i]==h[k]) f[i]=k;
else {
mid=find_mid(1,k,a[i]);
if (a[i]==h[mid]||a[i]<h[mid]) {
f[i]=mid;h[mid]=a[i];
} else {
f[i]=mid+1;h[mid+1]=a[i];
}
}
}
maxx=0;
for (i=1;i<=n;i++)
if (f[i]>maxx) maxx=f[i];
e[maxx+1]=200000;
for (i=n;i>0;i--)
if (a[i]<e[f[i]+1]) {
ans[i]=2;
if (a[i]>e[f[i]]) e[f[i]]=a[i];
}
for (i=1;i<=n;i++)
if (ans[i]==2) g[f[i]]++;
for (i=1;i<=n;i++)
if (ans[i]==2&&g[f[i]]==1) ans[i]=3;
for (i=1;i<=n;i++) printf("%d",ans[i]);
printf("\n");
return 0;
}