题目大意:给定一个序列,初始为空。现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置。每插入一个数字,求此时最长上升子序列长度
题解:因为从小到大插入,后插入的数不会影响前面的数的答案。对最后得到的序列求lis,第i行输出1-i的lis即可。
可以直接用平衡树模拟(vector能过……vector劲啊)插入,中序遍历得到序列。树状数组做法
我的收获:跪烂啊
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int M=100009;
int n,x,f[M],c[M];
vector<int> s;
vector<int>::iterator it;
void updata(int x,int v){
for(int i=x;i<=n;i+=i&(-i))
c[i]=max(c[i],v);
}
int query(int x){
int ret=0;
for(int i=x;i>0;i-=i&(-i))
ret=max(ret,c[i]);
return ret;
}
void work()
{
for(it=s.begin();it!=s.end();it++){
int p=*it;
f[p]=query(p-1)+1;
updata(p,f[p]);
}
for(int i=1;i<=n;i++)
f[i]=max(f[i-1],f[i]),printf("%d\n",f[i]);//取max,因为插入后LIS可能还是之前的序列
}
void init()
{
cin>>n;
for(int i=1;i<=n;i++) scanf("%d",&x),s.insert(s.begin()+x,i);
}
int main()
{
init();
work();
return 0;
}