『正睿OI 2019SC Day6』
<更新提示>
<第一次更新>
<正文>
动态规划#
dp早就已经是经常用到的算法了,于是老师上课主要都在讲题。今天讲的主要是三类dp:树形dp,计数dp,dp套dp。其中计数dp是我很不熟的,dp套dp是我没接触过,树形dp难的题我也不是很会做,所以感觉还是收获了不少,于是dp的总结将主要会以题解的形式呈现。
重要例题及简要题解#
Gcd counting:设fu,v代表以u为根的子树中,点权都能被v整除的最长链长度。对于每一个节点,只枚举它的因数,于是可以进行转移。
You are given a tree:对于一个给定的k,可以树形dp O(n)地计算答案,每次优先选子树内成立的方案,然后再考虑向上延伸即可。不难发现f数组不同的取值个数只有√n种,并且具有单调性,可以二分找段边界。
Vladislav and a Great Legend:考虑拆一下式子xk=∑ki=0Cix∗i!∗S(k,i),其中S(k,i)是第二类斯特林数,表示将k个元素拆分成i个集合的方案数。然后化简一下就发现要求∑XCif(X),涵义为所有非空点集对应的生成树标记了i条边的方案数之和。然后可以dp,fu,v代表以u为根的子树中标记了v条边的方案,背包即可。
Uniformly Branched Trees:考虑做树同构是要找重心的,那么dp计数肯定也要找重心作为根。设dpi,j,k表示节点数为i,共有j棵子树,每棵子树的大小都不超过k的有根树数量,然后dp。考虑单重心和双重心分别统计答案即可。
Multiplicity:设pi,j表示使用了a序列的前i个元素,造了长度恰好为j的子序列的方案数,第二维只需枚举因子转移,滚动数组即可。
MaximumElement:考虑计算的函数返回正确的方案数,设fi代表1−i的排列中有多少个是正确返回的,化简式子发现可以O(n),dp计算即可。
Hero Meet Devil:很经典的一个dp套dp,我们要把LCS的dp数组f压起来当作状态,于是想到差分。设fi,S代表T串考虑到了第i位,LCS dp数组差分后压缩为状态S的方案数,内层dp可以预处理,外层dp直接转移即可。
XHXJ′s LIS:考虑二分求LIS的dp做法,就可以dp套dp,由于二分做法中栈内元素是单调的,所以直接把每个数字是否出现再栈里压成一个状态,然后在外部做数位dp,状态为fi,op,S代表考虑了i位,与目标值大小关系为op,LIS栈状态为S的方案数,可以直接转移。
数据结构#
这次老师的数据结构也没有具体地讲算法,都是讲例题的。考虑到有些题还有有点套路,没有详解的必要,于是这里就写了个别有价值例题的题解。同时,我在这里理一个表,简单地写了我对各类数据结构和数据结构类算法的理解。
重要例题及简要题解#
1. 树链权值交:考虑序列上的版本,我们将第二个序列的值改为原数值在第一个序列上出现的位置,那么问题就转化为了在二个序列的区间内求在某个连续范围内的数字个数,可以用主席树解决。树上也是同理,只需对第一颗树链剖,对第二颗树建主席树即可。
2. 整除路径统计:考虑点分治,可以对每棵子树内的路径先计算最大值和权值和,然后考虑合并。把二元组按最大值大小排序,于是枚举一个点就确定了最大值,权值和直接在模p意义下处理,就能直接推出剩下一半最权值和需要是多少,用桶统计即可。
数据结构及数据结构类算法的理解#
并查集#
维护无向图连通性的有利工具,可以扩展为带撤销操作,多个意义的域或者是带边权等,有向关系可以转换为2−sat模型。
树状数组#
用于维护前缀和,支持修改和快速查询。可以扩展支持区间修改区间查询,也可以扩展到二维前缀和。在值域树状数组上倍增,可以实现查询第k大。
线段树#
序列维护区间信息的工具,前提要求是信息具有区间可加性,能够区间合并。当线段树作用在值域上时,还可以二分查找第k大。树上统计问题可能会用到线段树的合并算法,特别是用来计数的值域线段树。还可以维护扫描线算法,或者用来优化建图。
分块#
一种暴力算法,可以维护各种各样的信息。当需要维护的信息难以处理时,就可以考虑分块算法,主要问题在于思考如何处理整段信息和如何处理边界信息。可以扩展到树上,实现块状树。
点分治#
用于树上路径统计,常用的有两种方法:子树用数据结构维护的统计方法和先跑下所有子节点信息再统一计算贡献的统计方法,可能需要结合其他数据结构或计数算法。
cdq分治#
主要作用有三种:1. 解决偏序问题 2. 加速或维护动态规划 3. 处理动态的数据结构问题,化动态为静态。 对于1,核心思想在于部分有序的排序过程,对于2,核心思想在于计算左半边对右半边的转移,对于3,核心思想在于计算修改操作对查询操作产生的贡献。适用范围较广。
整体分治#
对所有询问同时进行二分答案,于是就可以对询问和修改操作进行分类处理,以得到格式相同的子问题,进行分治。对于限制较多,维数较高的数据结构问题可以考虑。
线段树分治#
也是时间分治算法的一种,和cdq分治很像,不过使用线段树来记录时间线上的信息,处理询问时只需dfs即可,回退时需要支持撤销操作。
Treap#
维护值信息的有效工具,功能较多,一般来说可以用值域树状数组和值域线段树代替。
Splay#
可以提取子树,操作区间的平衡树。使用范围较广,对于较复杂区间问题可以考虑。
LinkCutTree#
解决动态树问题时考虑使用,可以维护链信息,需要splay辅助。
trie/可持久化trie#
处理字符串问题以外可以处理异或最大值,可持久化就能处理区间异或最大值。
主席树#
前缀和版的线段树,可以利用前缀和的区间可减性实现对一个区间内的所有线段树进行操作,当然可以当可持节化线段树用。
莫队#
用来处理区间问题,要求区间支持转移。当转移受限时,可以拓展到回滚莫队,当有修改操作时,可以拓展到带修莫队。当然使用dfs序搬到树上是可以的。
树链剖分#
将树上路径问题和子树问题转化为不超过序列问题,再利用其他数据结构实现对序列的维护。
<后记>
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· 对象命名为何需要避免'-er'和'-or'后缀
· SQL Server如何跟踪自动统计信息更新?
· “你见过凌晨四点的洛杉矶吗?”--《我们为什么要睡觉》
· C# 从零开始使用Layui.Wpf库开发WPF客户端
· 编程神器Trae:当我用上后,才知道自己的创造力被低估了多少
· C#/.NET/.NET Core技术前沿周刊 | 第 31 期(2025年3.17-3.23)
· 接口重试的7种常用方案!