杂记
钦定顺序特别重要,这不仅关乎到可能的去重,也关乎到简化问题。当然,错误的顺序可能会使问题更复杂(来自图上状压计数)。
如果觉得题目无从下手,考虑 DP(来自蜜蜂搬家)。尝试着设计一个不管有多复杂的 DP 状态,然后一点一点把握题目中各个要素的关系,找到转移的途径;考虑尽量简洁地描述题目要素之间的关系,不管这种关系看起来多么地不可转移。那是实现的事情;一定要敢 DP!
如果有机会——如果有机会——尽量不要把算法大改特改。请最好保持它本来的样子——这样内聚性比较好,调起来也比较好调,不会出现难以名状的客制化错误(来自某个线段树优化长剖,其中由于链长最大为 \(m\) 的题设改动了长剖的结构却没有注意到,导致剖假了)。
准备扫尾的时候好好想想你的扫尾复杂度对不对(来自最短路,使用了回溯到 \(S\) 求路径长度的方式,复杂度 \(O(n^2)\)...work 部分的复杂度是 \(O(m)\))!!!
复杂度平衡。复杂度平衡。复杂度平衡。
拓扑排序也是排序!倒不如说它是验证序的存在性的。存在的话随便找一条。
不要老是试图对不要求 \(O(1)\) 的题目猜结论然后打补丁(来自 \(\text{CF1698C,CF1728D}\))。
分块之于线段树,恰如齐纳协议之于 OGAS。它只有一层,明白吗?想想分块的特点是什么——块内暴力!线段树做得到吗?区间太大就做不到。分块恰恰像是舍弃了嵌套,换取了暴力...
给出一种维护树上若干点是否共链的做法:维护一个 set,内部关键字为到起点的距离,加的时候求 \(lca(s,x)\oplus lca(x,t)\oplus lca(s,t)\),可以证明这就是这三条路径的交点(如果有),对等于 \(s/t/x\) 分讨,如果改 \(s\) 那么对距离做整体偏移。删除时同理,注意整体偏移。
注意检查 fileit()
的注释是否去掉了,以及,注意检查 For
和 Fort
之间的差异。
一系列取最小值操作的结果和其原数组具备某种...单调不减性?如果原数组中某个数字变小了,那么结果绝不可能变大。于是有一些奇怪的思路可以将操作后的约束变为操作前的约束,譬如 \(\text{CF2116D}\)(该题如果想单纯逐步手推约束关系的话,显然某次操作后某个数字只可能是确定的值或者大于等于某个值;于是容易发现当 \(x=z\) 时,如果 \(c_y\geq k_1,c_x=k_2,k1<k2\),那么有 1.来自 \(y\),变成 \(c^{'}_y=c_x,c^{'}_x\geq c_x\) 和 2.来自 \(x\),变成 \(c^{'}_x=c_x,c^{'}_y\geq c_x\) 两种情况。)。
multiset 的作用是允许你放多个相同的元素,不是让你写一个垃圾偏序把不同元素当成相同的。虽说有的题可能看起来没事,但是你试图 erase(find()) 的时候就知道错了,直接退化成随机删除元素。