$Splay + 树状数组$
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 100010, INF = 2e9;
struct node {
int s[2], p;
int val;
int size;
void init(int _val, int _p) { s[0] = s[1] = 0, p = _p, val = _val, size = 1; }
} tr[N];
int root, idx;
int n;
int f[N];
int a[N], k;
int td[N];
int res[N];
void pushup(int u)
{
tr[u].size = tr[tr[u].s[0]].size + tr[tr[u].s[1]].size + 1;
}
void rotate(int x)
{
int y = tr[x].p, z = tr[y].p;
int k = tr[y].s[1] == x;
tr[z].s[tr[z].s[1] == y] = x, tr[x].p = z;
tr[y].s[k] = tr[x].s[k ^ 1], tr[tr[x].s[k ^ 1]].p = y;
tr[x].s[k ^ 1] = y, tr[y].p = x;
pushup(y), pushup(x);
}
void splay(int x, int k)
{
while(tr[x].p != k)
{
int y = tr[x].p, z = tr[y].p;
if(z != k)
if((tr[z].s[1] == y) == (tr[y].s[1] == x)) rotate(y);
else rotate(x);
rotate(x);
}
if(!k) root = x;
}
void insert(int val)
{
int u = root, p = 0;
while(u) p = u, u = tr[u].s[val > tr[u].val];
u = ++ idx;
if(p) tr[p].s[val > tr[p].val] = u;
tr[u].init(val, p);
splay(u, 0);
}
int get_k(int k)
{
int u = root;
while(u)
{
if(tr[tr[u].s[0]].size >= k) u = tr[u].s[0];
else if(tr[tr[u].s[0]].size + 1 == k) return u;
else k -= tr[tr[u].s[0]].size + 1, u = tr[u].s[1];
}
return -1;
}
void dfs(int u)
{
if(tr[u].s[0]) dfs(tr[u].s[0]);
if(tr[u].val > -INF && tr[u].val < INF) a[++ k] = tr[u].val;
if(tr[u].s[1]) dfs(tr[u].s[1]);
}
int lowbit(int x)
{
return x & -x;
}
void add(int x, int val)
{
for(int i = x; i <= n; i += lowbit(i)) td[i] = max(td[i], val);
}
int query(int x)
{
int res = 0;
for(int i = x; i; i -= lowbit(i)) res = max(res, td[i]);
return res;
}
int main()
{
scanf("%d", &n);
insert(-INF), insert(INF);
for(int i = 1; i <= n; i ++)
{
// splay构造序列
int x;
scanf("%d", &x);
// 按插入要求构造
int l = get_k(x + 1), r = get_k(x + 2);
splay(l, 0), splay(r, l);
int u = ++ idx;
tr[u].init(i, r);
tr[r].s[0] = u;
pushup(r), pushup(l);
splay(u, 0);
}
dfs(root); // 获取序列
for(int i = 1; i <= k; i ++) add(a[i], f[a[i]] = query(a[i]) + 1);
// 每次插入一个元素,如果该元素对当前答案有影响,则取f[i], 否则就取f[i - 1]
for(int i = 1; i <= n; i ++) f[i] = max(f[i], f[i - 1]);
for(int i = 1; i <= n; i ++) printf("%d\n", f[i]);
return 0;
}