计算从左往右的最长上升子序列 L 在计算从右往左的最长下降子序列 R
如果L[i] + R[i] - 1 < 最长上升子序列的长度 那么就一个都不是
否则统计长度为 i 的子序列位置的个数(满足在最长上升子序列内) 如果有且仅有一个长度为i的位置 那就是每一个子序列都包含
其他的就是至少一个
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<deque>
#include<iostream>
#define SF scanf
#define PF printf
using namespace std;
typedef long long LL;
const int MAXN = 100000;
int A[MAXN+10], d[MAXN+10], Inc[MAXN+10], Dec[MAXN+10], ans[MAXN+10], cnt[MAXN+10];
int n, m, inc, decrease;
void dp()
{
memset(d, 0x3f, sizeof(d));
for(int i = 1; i <= n; i++) {
int pos = lower_bound(d+1, d+n+1, A[i]) - d;
Inc[i] = pos;
if(d[pos] == d[0]) inc++;
d[pos] = A[i];
}
memset(d, 0x3f, sizeof(d));
for(int i = n; i > 0; i--) {
int pos = lower_bound(d+1, d+n+1, -A[i]) - d;
Dec[i] = pos; d[pos] = -A[i];
}
}
int main()
{
SF("%d", &n);
for(int i = 1; i <= n; i++) SF("%d", &A[i]);
dp();
for(int i = 1; i <= n; i++) {
if(Inc[i] + Dec[i] - 1 < inc) ans[i] = 1;
else cnt[Inc[i]]++;
}
for(int i = 1; i <= n; i++) {
if(ans[i]) PF("1");
else if(cnt[Inc[i]] == 1) PF("3");
else PF("2");
}
}