[TJOI2013]最长上升子序列 - 洛谷https://www.luogu.com.cn/problem/P4309先用vector模拟一遍插入过程,又因为是从1-n的插入,所以我们可以直接遍历插入后的数组,举一个例子当i出现时,小于i的数字肯定也在数组里,所以我们只需要顺序遍历就可以了,然后我们可以通过用树状数组记录小于 i 的dp最大值,这里dp[i]可以理解为以i为结尾的最大递增子序列的元素数量,一道很好的思维题。
#define lowbit(x) ((x)&(-x))
int n;
int tr[MAXN];
vector<int> v;
void update(int x,int val){
for(int i=x;i<=n;i+=lowbit(i)){
tr[i]=max(tr[i],val);
}
}
int query(int x){
int rec=0;
for(int i=x;i;i-=lowbit(i)){
rec=max(rec,tr[i]);
}
return rec;
}
int dp[MAXN];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
v.insert(v.begin()+x,i);
}
for(int i=0;i<n;i++){
int t=v[i];
update(t,dp[t]=query(t)+1);
}
for(int i=1;i<=n;i++){
printf("%d\n",dp[i]=max(dp[i],dp[i-1]));
}
return 0;
}