思维trick总结
先开始列举,明天再整理
- 原图 \(M\) 再加上边集 \(E\) 之后的最小生成树一定边会在原图最小生成树和新增边集 \(E\) 中选,例题:P14362 [CSP-S 2025] 道路修复 / road
- 启发式合并的时间复杂度证明:有一个正整数 \(a\), 定义每次操作为选择一个正整数 \(b\), \(b >= a\), 然后将 \(a = a + b\),则:最多 \(log_2n\) 次操作,能使 \(a >= n\),这一性质能将启发式合并的时间复杂度从 \(O(n^2)\) 降到 \(O(nlog_n)\), 这里假定一次合并的复杂度为 \(O(nlog_n)\),例题:塔 (tower)
- 对于将 \(n\) 个人分成若干组,每个人有自己的 \(c_i\), 合法的分组当且仅当对于任意一组A, 有 \(\min_{i \in A} c_i >= A.size\),求分配的方案数,这可以将问题转化为已经分成了若干组,然后每组已经预定了有恰好\(s_i\) 个人 (\sum_{s_i} = n, 然后往里面塞 \(c_j > s_i\) 的合法人,求方案数,这样子的分组内定了,方便 \(dp\) 无后效性,例题:研究性学习 (group)
- 对于有环的\(dp\), 或者是递归,可以遍历环上的每一个点,断开,做 \(k\) 次计算,这样子的时间复杂度会上升,如果开始 \(dp\)/递推的点并不在意,那么可以直接用 \(bool\) 数组来判断就好了,亦或者可以特判掉环然后直接 \(dp\)/递推,这样子也没后效性。例题:灯火幽暗 (dark)
- 对于正整数 \(a\),任意一个正整数 k, 都有 \(a \ mod \ k < a / 2\). 例题:长路漫漫 (long)
- 正难则反,例题 P1450 [HAOI2008] 硬币购物
- 转换类型,其中最常见的是 数学/dp 转 图论 ,例如: 琴师的箭羽,这道题目发现的是如果你一个 \(a_i = 0\) 那么你一定要填掉他, 将 \(a_i = i\), 如果没有 \(i\) 还好,有的话那么就要继续填补,前面不能变,就只能改后面的,所以, 设 \(rev_i\) 为未操作之前的权值为 \(i\) 的下标,所以有 \(a_{rev_i} = rev_i\), \(a_{rev_{a_{rev_i}} = rev_{a_{rev_i}}\) 以此类推,发现这可以建边,之前的权值,指向现在的权值,可以发现,结束的时候,一定会有一个点指向 \(i\), 即有一个环,所以这个时候就直接找环就好了,每次如果进入了一个新的连通块,就把答案加上这个连通块的大小就可以了,这是一类,后面的也类似
- 树上博弈:基本上是树上 \(dp\) (就是 \(sg\) 函数),考虑对于 \(f_i\) / \(g_i\) 表示先后手和当前在以 \(i\) 的子树上的最优解,通过先后手交换来转移,例题:P4096 [HEOI2013] Eden 的博弈树
- 反悔贪心:主打一个调整法,比如说改成 "aaaaaaa\dots a" 来算答案上界,然后再去反悔,减少多余花费,再比如说,对于问你要多少次操作才能将其没有长度为 \(len\) 的回文串,先改第一个长度为 \(len\) 的回文串最后一个改掉,再看,不行,再改。。以此类推。例题:CF196D The Next Good String, P12667 [KOI 2023 Round 2] 傻瓜锁
- "这个括号序列是合法的" 与 "左括号和右括号的总数相等且对于每一个前缀,左括号数恒大等于右括号数" 是等价的,例题:AT_arc194_d [ARC194D] Reverse Brackets
- 分段 \(dp\), 例如例题中的,要将它分成 \(4\) 段, 第 \(1\) 段为 \(0\), 第 \(2\) 段为 \(1\),第 \(3\) 段为 \(0\),第 \(4\) 段为 \(1\), 然后题目就从绿题变成橙题了,最后只要反转 \(2,3\) 段即可,例题:照了个照(photo)
- 前缀和:对于考虑要让正整数 \(a\) 刚好等于 \(k\) 或许有点难,就可以考虑对于 \(\le L\) 进行 \(dp\), \(ans = f_l - f_{l-1}\) 就是了,例题 :AT_abc180_f [ABC180F] Unbranched
- 如果时间复杂度超了,或算法太过复杂,可以考虑合并状态或减少需要考虑的状态来降低复杂度 (例题:加法(add))
- 树形结构具有很多优美的性质,可以通过分析度数与环来证明树形结构:Shifting Dominoes
- dfs 树是很重要的思维方式,通常我们分析树边和非树边能得到很多有意思的性质。如果是有向图还要考虑哪个点为根更好分析:James and the Chase;或者可以通过 dfs 树直接给出构造:Nezzar and Hidden Permutations;Weighting a Tree
- DAG 具有很好的性质,所以就算是遇到一般图时,也可以先思考在 DAG 的环境下如何处理:Sergey's problem
- 双指针加映射,对于一些类似 "权值为 \le x 的数和 > x的数分开计算,问每个x的值" 我们可以考虑将 \(> x\) 设为 \(1\), 将 \(\le x\) 设为零,权值用线段树维护,然后发现遍历一遍后每个数只从 \(1\) 到 \(0\) 操作至多一次,然后就可以当作单点修改,剩下的就是线段树了,这样子的时间复杂度就从 \(O(n^2)\) 到了 \(O(nlog_n)\)

浙公网安备 33010602011771号