题解:P9928 [NFLSPC #6] 来点不那么魔怔的题面

· · 题解

省流

用树状数组优化 DP,适合有树状数组基础的同学参考。

朴素DP

求长度为 k 的严格上升子序列,其他题解都有介绍,或者把最长上升子序列加个到 k 就跳出循环,总之是枚举两层,第二层找到最大的结尾小于 a_i 的最长上升子序列。

树状数组优化

从小到大枚举,找到结尾小于 a_i 的最长上升子序列,本质就是求出所有小于 a_i 的数值对应的最大 dp 值,这区间最大值,不就可以用树状数组优化了吗?

维护两个函数 qr(x)up(x,y)

$up(x,y)$ 作用是将树状数组的 $x$ 位置的值更新为 $y$。那么我们更新完 $dp_i$ 后需要再把更新后的值存入树状数组,也就是执行 $up(a_i,dp_i)$。 这样就完成了用树状数组优化 DP 的操作。 # 关键代码 ```cpp void up(int x,int v){ for(;x<=n;x+=x&-x)if(tr[x]<v)tr[x]=v; } int qr(int x){ int r=0; for(;x;x-=x&-x)if(tr[x]>r)r=tr[x]; return r; } ```