Tips

  • 我们真的需要关心这个量吗?

  • 需要维护序列,任意删除元素,末尾添加元素,可以用值域(开 \(V + Q\))动态开点线段树,带 vector 可求答案。(列队

  • 形如 \(a_i \gets a_{i-1}+a_{i+1}-a_i\) 之类的操作,相当于交换差分数组中的某两个元素。(方差最小化和

  • 求两个排列的最长公共子序列,可以将一个排列排序再做。

  • 一些神秘的暴力,可以观察有没有多余操作(有关值域等),通常是看看有没有【加倍】或【减半】,使暴力优化成 \(\log\)

  • 位运算拆位老套路。

  • 和序列 \(A\) 中连续段有关的 \(\sum f(A)\) 题,可通过每个元素的【切割贡献】转化成普通计数。this.

  • 构造题中给的带 $ \le \frac{1}{?} \cdot ...$ 的神秘条件,可以考虑构造出 \(?\) 种方案,总和是 \(...\),于是代价最小的方案的代价必然 \(\le \frac{1}{?} \cdot ...\),就是一组可行的解。this.

  • 判定一条边是否能成为图上某两定点之间某路径第 \(k\) 大的,可以将图上大于该边的边权设为 1,小于等于的设为 0,跑最短路,看看最短路是否等于 \(k-1\)

  • DP 时,如果状态数很多而结果的值域很小,不妨试试交换某一维状态和值域。

  • DFS 枚举【分组】的时候,可以尝试将状压后的还未分组的集合传参,每次递归的时候保证当前集合中第一个未分组的元素要被处理掉,这样常数很小。(由枚举每个元素分在哪一个组,并动态记录当前有几组进化而来)this.

  • 需构造排列,可考虑随意构造两两不同的序列再离散化。

  • T1 级别的枚举题,而高次方枚举过不了的,考虑折半。

  • 序列中【可达性】问题,可以考虑预处理每个点能达到的最前/最后点下标,贪心地判断。(如果后点能到达的最前点小于/大于前点,那么可行,因题而异)

  • DP 有的时候可以倒着搞。

  • 树上两个结点没有祖孙关系,等价于其 DFS 序中管辖的区间不相交。

  • 序列升序等价于差分数组最小值非负,单点修改、区间修改 set 可做。当然也可以用线段树维护两边最小值最大值。

  • 网格图中间有一个连通块,要想判断一个回路是否把连通块包住,等价于从连通块中任意一点向任意一边引一条射线,回路经过这条射线奇数次。和判点在多边形内部很像。

  • 点分治的另一个算贡献的写法:分治中心下所有点对,减去两个点在同一子树的情况。

  • 基环树上拓扑排序也是一种思路。

  • 贪心时,可以考虑一个临界的合法情况,再进行调整。

  • 子串是后缀的前缀。

  • 正者扫一遍,倒着扫一遍。

  • \(x=\sum_{i=0}^{+\infty} \left [x>i \right]\)

  • 经典的多米诺骨牌(\(1 \times 2\))覆盖 \(n \times m\) 矩阵,可以通过相邻黑白染色转化。

  • \(k\) 大值的技巧:二分、超级钢琴,以及直接枚举钦定 \(k\) 大值。

  • CDQ 要手法去掉相互贡献的情况。

  • 动态问题可以用 CDQ 转成静态问题。比如,我们要实现一个结构,支持插入和查询。但是不特殊的插入是困难的,整段重构是简单的,而且每一个插入对询问是独立的。这时可以通过 CDQ 将动态问题转化成每一个插入进来的点,对后面的贡献,从而变成静态。

  • 有加入、删除、查询,且删除是困难的,撤销是简单的,可以考虑线段树分治。

  • DP 不止能考虑【前 \(i\) 个点】,也能从值域的角度,从小到大 DP。

  • 树形 DP 两个事:

    • \(u\) 为根的子树添加一个父亲。
    • \(u\) 为根的子树,其中有一些孩子已经转移,添加一个子树。
  • border 首尾都有一个。如果通过一些神秘的变换让他们在一起,就有可能出偶回文串。

  • DP 算所有可能的序列的总权值的题,不一定要从算【确定序列】的权值入手,可以考虑直接算总贡献。比如,考虑权值是某个值的序列有多少个,考虑一定情况有多少种序列会产生贡献,等等。

  • 某一权值【恰好】等于多少的计数题,可以考虑变成【至少】,然后容斥。

  • 二项式反演:先钦定,再任选,可认为是分步。

  • 地图的范围比较大,但是横纵坐标有限,考虑扫描线。

  • 关于 DAG 状压计数一个常见套路(必记!)是:钦定零度点集,简单容斥去重。

  • AC 自动机可以看成是两棵树拼起来:Trie 树和 fail 指针构成的树。

  • 排列计数,但是状压:记 \(p_i\)\(i\) 的一个映射。考虑设 \(f(S)\)\(n\) 个元素满射至 \(S\) 的方案数。\(g(S)\)\(n\) 个元素普通映射至 \(S\) 的方案数。可以去掉一些枚举子集的部分。(SDOI 小星星)

  • 对于覆盖类问题,考虑区间 DP。

  • 括号匹配建模。(Canteen, including easy version and hard version

  • 树的问题考虑链怎么做,再想怎么拓展。

  • 分组计数问题,可以这么定义状态:\(f_{i,j}\) 表示,考虑到 \(i\),前面有 \(j\) 个空位没有填。转移就考虑这 \(j\) 个空位会被填掉还是保留。

  • 发现每一种分组方案可以看做给一个 \(b\) 数组填数,表示 \(i\) 所在组的元素个数。那么分组就可以视为给每个 \(b_i\) 填一个 \([1,a_i]\) 的数。记 \(j\)\(b\) 中出现了 \(t_b\) 次,一个 \(b\) 数组是有效的等价于所有 \(t_i\)\(i\) 的倍数。
    再考虑对于一个确定的 \(b\) 数组,贡献是什么。(一 \(b\) 对多方案)

  • “乱向树”上的计数,可以先考虑有根的外向树和外向森林上怎么做,再考虑钦定一些反向边为割边,做带容斥系数的 DP。

  • 两人博弈,一个想让答案大,一个想让答案小,可以用二分的方式思考,二分答案 \(k\),序列(或其他结构)中,\(\ge k\) 的数变成 \(1\),其他变成 \(-1\)(或 \(0\)),转化成普通的,胜负的问题。

posted @ 2025-09-06 16:11  Water_M  阅读(9)  评论(0)    收藏  举报