题解:P17859 白露 / ros
似乎有更简单的做法?
考虑如何设计状态去做 dp。尝试插入一个
- 如果
a_{i+1} \ge \max :那么a_{i+1} 不会受到任何约束。 - 如果
a_{i+1} < \max ,那么a_{i+1} 一定会和\max 在树上相邻,否则不合法。但是这并不充分,思考一下,我们发现a_{i+1} 还会收到除了\max 其他数的约束,我们先考虑\sec 的约束。- 如果
\sec \le a_{i+1} < \max ,则a_{i+1} 不会被\sec 约束。 - 否则,则
a_{i+1} 必须位于\sec 的邻域里。
- 如果
由于树上两个不同点
前面的转移应该都是平凡的,接下来考虑最大值改变的情况。记改变后的最大值为
- 如果
G_{j'} \cap G_j = \varnothing :直接转移(f_{i,j,k,0}+f_{i,j,k,1}) \to f_{i+1,j',j,0} 。 - 否则,记
G_{j'} \cap G_j = u', G_{j} \cap G_k =u :- 对于
f_{i,j,k,0} 的转移,特殊点u' 存在的条件是必须要有k \le u' < j ,所以转移为f_{i,j,k,0} \to f_{i+1,j',j,[k \le u' < j]} 。 - 对于
f_{i,j,k,1} 的转移,特殊点u' 除了上述条件,若u'=u ,也可以直接转移。所以转移为f_{i,j,k,1} \to f_{i+1,j',j,[k \le u' < j] \vee [u=u']} 。
- 对于
观察一下,状态数是
考虑如何优化,首先从优化转移下手。转移
考虑什么时候会取到
考虑接下来如何优化,肯定需要从状态数上面做文章。一个想法是观察到大部分时候我们并不关心
考虑如何证明这件事情:
- 对于
f_{*,*,*,0} ,我们重设计新的状态:f_{i,\max,k,0/1} 代表当前最大值为\max ,当前次大值\le 最大值邻域的第k 大值。特殊地,我们需要单独记\sec=0 的状态。这样的总状态数是\sum (d_i + 1) \le 2n ,这里d_i 是i 邻域比i 编号小的数。 - 对于
f_{*,*,*,1} ,我们如果沿用上面的状态会无法转移,但是我们发现,合法的(\max,u) 的对数是O(n) 的,而我们又发现,对于一对(\max,u) ,合法的\sec 会被划分成\min(d_{1,\max},d_{2,u})+1 个等价类,这里d_{1/2,u} 代表u 周围编号比u 小的 / 大的数。放缩一下,\sum \min(d_{1,\max},d_{2,u})+1 \le \sum d_{u}+1 \le 2n 。
所以我们证明了确实只会有