Description
给定一个序列,初始为空。现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置。每插入一个数字,我们都想知道此时最长上升子序列长度是多少?
Input
第一行一个整数N,表示我们要将1到N插入序列中,接下是N个数字,第k个数字Xk,表示我们将k插入到位置Xk(0<=Xk<=k-1,1<=k<=N)
Output
N行,第i行表示i插入Xi位置后序列的最长上升子序列的长度是多少。
Sample Input
3
0 0 2
Sample Output
1
1
2
HINT
100%的数据 n<=100000
分析
用treap维护序列后直接求lis
代码
#include <bits/stdc++.h>
#define N 100005
#define INF 0x7fffffff
struct
{
int l,r;
int size;
int rand;
int cover;
}t[N];
int root, size;
void pushUp(int k)
{
t[k].size = t[t[k].l].size + t[t[k].r].size + 1;
}
void rttr(int &k)
{
int tmp = t[k].l;
t[k].l = t[tmp].r;
t[tmp].r = k;
pushUp(k);
pushUp(tmp);
k = tmp;
}
void rttl(int &k)
{
int tmp = t[k].r;
t[k].r = t[tmp].l;
t[tmp].l = k;
pushUp(k);
pushUp(tmp);
k = tmp;
}
void insert(int &x,int rank)
{
if (!x)
{
x = ++size;
t[x].size = 1;
t[x].rand = rand();
return;
}
t[x].size++;
if (t[t[x].l].size < rank)
{
insert(t[x].r,rank - t[t[x].l].size - 1);
if (t[t[x].r].rand <t[x].rand)
rttl(x);
}
else
{
insert(t[x].l,rank);
if (t[t[x].l].rand < t[x].rand)
rttr(x);
}
}
int tot;
int num[N];
void dfs(int x)
{
if (!x)
return;
dfs(t[x].l);
num[++tot] = x;
dfs(t[x].r);
}
int pos[N];
int ans[N];
int mx;
int n;
void slove()
{
memset(pos,127,sizeof(pos));
pos[0] = -INF;
for (int i = 1; i <= n; i++)
{
int tmp = std::upper_bound(pos,pos + mx + 1,num[i]) - pos;
if (pos[tmp - 1] <= num[i])
{
pos[tmp] = std::min(pos[tmp],num[i]);
ans[num[i]] = tmp;
mx = std::max(tmp,mx);
}
}
}
int main()
{
scanf("%d",&n);
for (int i = 1; i <= n; i++)
{
int x;
scanf("%d",&x);
insert(root,x);
}
dfs(root);
slove();
for (int i = 1; i <= n; i++)
{
ans[i] = std::max(ans[i - 1], ans[i]);
printf("%d\n",ans[i]);
}
}