题目大意:给定一个序列,依次将1~n插入,问每次插入之后序列的LIS长度是多少
由于是从小到大插入,因此插入一个数之后显然是不影响之前的答案的
因此我们不妨先用平衡树搞出插入之后的序列,再求一遍LIS即可
注意最后每个点还要对前面的取一下max 因为插入后LIS可能还是之前的序列
蒟蒻的我到底还是把平衡树写挂了。。。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 100100
using namespace std;
int n,a[M],ans[M];
namespace Treap{
struct abcd{
abcd *ls,*rs;
int val,key,size;
abcd(int x);
void Maintain();
}*null=new abcd(0),*root=null;
abcd :: abcd(int x)
{
ls=rs=null;
val=x;
key=rand()*(bool)x;
size=(bool)x;
}
void abcd :: Maintain()
{
size=ls->size+rs->size+1;
}
void Zig(abcd *&x)
{
abcd *y=x->ls;
x->ls=y->rs;
y->rs=x;
x=y;
x->rs->Maintain();
}
void Zag(abcd *&x)
{
abcd *y=x->rs;
x->rs=y->ls;
y->ls=x;
x=y;
x->ls->Maintain();
}
void Insert(abcd *&x,int y,int z)
{
if(x==null)
{
x=new abcd(z);
return ;
}
if(y<=x->ls->size)
{
Insert(x->ls,y,z);
if(x->ls->key>x->key)
Zig(x);
}
else
{
Insert(x->rs,y-x->ls->size-1,z);
if(x->rs->key>x->key)
Zag(x);
}
x->Maintain();
}
void Output(abcd *x)
{
static int cnt;
if(x==null)
return ;
Output(x->ls);
a[++cnt]=x->val;
Output(x->rs);
}
}
namespace BIT{
int c[M];
void Update(int x,int y)
{
for(;x<=n;x+=x&-x)
c[x]=max(c[x],y);
}
int Get_Ans(int x)
{
int re=0;
for(;x;x-=x&-x)
re=max(re,c[x]);
return re;
}
}
int main()
{
using namespace Treap;
using namespace BIT;
int i,x;
cin>>n;
for(i=1;i<=n;i++)
{
scanf("%d",&x);
Insert(root,x,i);
}
Output(root);
for(i=1;i<=n;i++)
{
int temp=Get_Ans(a[i])+1;
Update(a[i],temp);
ans[a[i]]=temp;
}
for(i=1;i<=n;i++)
ans[i]=max(ans[i],ans[i-1]);
for(i=1;i<=n;i++)
printf("%d\n",ans[i]);
return 0;
}