算法竞赛中常见trick
本文主体译自 Collection of little techniques 并有所删改
前言略
1.bitset优化空间
考虑 DAG上的可达性 ,给定一个 个节点和 条边的 DAG,包含 次查询,其中查询的形式为 "顶点 是否可由顶点 到达" ,其中 且不允许有类似 的空间复杂度,其中包括开 个长度为 的 bitset
一个比较经典的解法是让 成为一个 bitset ,当 可以到达 时令 。这个方法在大多数情况是可行的,但是 个长度为 的 bitset 也会占用大量内存,因此我们可以用 位整数来代替 bitset ,并重复该算法 次。在第 次执行该算法时,我们令 成为一个 位整型用来储存 是否可以到达 。
2.避免在莫队中出现 log
考虑如下问题:给定一个长度为 的序列和 次询问,询问区间 mex ,不强制在线。
线段树固然可行,但我们现在要考虑莫队。
在利用莫队维护 mex 的时候,我们同时也需要一个 set<int>
来维护在该区间所有未出现的整数,这样在每次指针后我们都可以用 的复杂度来维护答案,这样莫队总的复杂度就做到了 ,但是这样太慢了!
显然复杂度的瓶颈是 set<int>
,我们之所以用它是为了支持以下操作:
- 插入一个元素,当前单次复杂度 ,需要操作 次
- 删除一个元素,当前单次复杂度 ,需要操作 次
- 查询最小值,当前单次复杂度 ,需要操作 次
我们注意到前两种操作更频繁一点,但他们的时间复杂度相同,因此我们可以牺牲最后一个操作的复杂度,使得前两种操作更高效。
我们需要这样一个数据结构:
- 插入元素
- 删除元素
- 查询最小值
因此我们可以将值域分块,插入删除显然可以 完成,同时我们维护是否每个块中的元素已经全部出现,自小到大找到一个非满的块暴力查询即可。
这是在莫队中至关重要的一件事,确保指针能在 复杂度下移动,即使有时需要牺牲查询的复杂度
3.根号优化背包/ “3k trick”
假设有 个物品,每个物品都有一个非负数权值 ,且 ,询问是否能从中选出一些物品使得其权值和为 。
我们假设有三个相同权值的物品 。注意到用 可以替换掉这三个物品,我们可以重复这个过程直到每个权值至多有两件物品,且有 ,因此至多只有 个物品。因此我们可以直接进行背包,同时物品的数目减少至 个,这在大部分情况下是更好的复杂度
这个技巧大多出现在序列 能被某些特殊形式划分的时候,例如他们可能代表一个图的分量,请看示例:
我们考虑把整个过程看成二分图,最初的输入会产生一定的分量,我们可以考虑翻转其中的一部分使得两边大小尽量相同。最初我们可以翻转全部的分量,使得左边的分量变小。然后我们可以每次选择翻转一部分分量,使得左侧部分大小增加 ,且 为定值。 这样就可以利用上述技巧解决掉整个问题了。
4. 不同种元素的划分方案数
该问题与上一个问题有关,对于长度为 的非负整数序列有 ,我们能得到不同的 的取值至多只有 种。
证明:
取出 中全部各不相同的值,并将其按升序排序得到 ,由于 序列中均为非负整数,因此有 ,进而可以得到
且有 ,所以 至多只有 种。
5.从背包中删除元素
假设有 个物品,第 个物品的价值是 。你需要维护一个 数组,其中 表示得到价值总和恰好为 的物品有多少种方式。
向背包中加入物品是个经典问题
// 从大到小转移保证不会被重复选择
for(int i = MAX_Val; i >= val; i--) {
dp[i] += dp[i - val];
}
要是想撤销刚才的操作,我们只需要将一切都倒过来即可
// 撤销新加入的状态
for(int i = val; i <= MAX_Val; i++) {
dp[i] -= dp[i - val];
}
需要注意的是 数组的状态与物品加入的顺序无关。实际上,刚才所展示的代码可以撤销掉任意一个价值为 的物品,我们可以通过假设该物品是最后加入的来证明其正确性。
如果我们仅仅是为了检验是否有得到价值恰好为 的方案,而不关心有多少种方案的时候依然可以用这个技巧的变种。我们依然是计算方案数,并检查方案数是否为 ,由于方案数可能会很大,我们可以选取一个大素数作为模数。虽然可能会出现错误,但是如果我们随机选择一个足够大的模数,该方法的成功率是相当可观的。
6.调和级数
有结论
该结论可以用来计算某些算法的复杂度。通常来说这类算法都类似这样:
for(int i = 1; i <= n; i++)
for(int j = i; j <= n; j += i)
// 某些操作
对于一个确定的 来说,有着不超过 个 的取值,且他们总的数目同上述结论可以推得
因此该算法时间复杂度为
本文作者:Jadebo1
本文链接:https://www.cnblogs.com/Jadebo1/p/17609897.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步