数据结构
单调栈
(1.1) 可撤销回退单调栈,插入元素时二分插入,记录栈顶和栈内信息丢进另外一个栈,回退时(O(1))撤销。
线段树合并
(1.2) 两颗线段树在合并的时候可以顺便维护一些信息。
(ST)表
(1.3) 区间中的点分别对应连边的时候可以用(ST)表处理。
(Trie)树
(1.4) (01Trie)整体加一可以通过从低位向高位建(Trie)树实现。
(1.4.2) 可以在博弈论问题里用来维护(sg)值。
树上问题
(1.5.1) 树上路径问题,一般分子树内和祖先讨论。
(1.5.2) 点集的(lca = dfs)序最大最小的两个点的(lca)
动态规划
矩阵加速
(2.1.1) 边权比较小的图,可以将每个点拆开,这样只会存在边权为一的边,就可以矩阵加速了。
(2.1.2) 对于多次询问,可以预处理出幂次为(2^k)的转移矩阵,询问时二进制拆分计算。
根号平衡
(2.2) 某个要求的答案例如划分数可能有两种不同的(Dp),状态是不一样的,取(B = sqrt(n)),一种转移(< B)的,另外一种转移(>= B)的,这样根号平衡下来能做到(O(nsqrt(n)))。
分析组合意义
(2.3) 求(sum a_i ^ 2),其中(a_i)是方案数。
那么就相当于有两个东西,摆放的方案相同的数量。
序列哈密顿回路
(2.4) 类似插头(dp)用状态存折线。
费用提前计算
UVA1336 修缮长城 Fixing the Great Wall
贪心
(3.1) 当有两种操作且互相影响时,可以考虑枚举其中一种操作的数量,算出另一种操作最大可能获利再相加。
(3.2) 当有两个数列(A)和(B),求(A)中某数和(B)中某数进行运算得到的最大的(k)个,可以对于(A)中每个数在(B)中找到运算的最大值,加入堆,每次弹出堆顶,对于堆顶的(A)中的数再找一个未使用过的(B)中的数使得运算结果最大,再次加入堆,这样弹出来的前(k)个就是答案。
二分
(4.1) 查区间中位数时,二分一个答案(mid),把所有(>= mid)的数值设成(1),(<mid)的值设为(-1),查询区间内的和是否(> 0)。
(4.2) 形如“最大值最小”,“最小值最大”的题面大概率是先二分再贪心。
数学
处理式子的小(Trick)
(5.1) 求(sum_{i = 1}^n a^i),构造(s_i = sum_{j = 1}^{2^i} a^j),则可以通过倍增在一个(log)的复杂度内算出答案。
线性规划
(5.2) 可以通过线性规划表示平面上的一个凸多边形。
博弈论
(5.3) (n-nim)游戏可以获胜当且仅当其二进制数在(n + 1)进制下做不进位加法等于(0)。
这是因为先手取了(x)个后,后手总能取(n + 1 - x)个使加法总和再次等于(0)。
位运算
(5.4.1) 三进制下的运算可以通过用二进制数记录两个数(1)和(2)的位置用位运算加速。
(5.4.2) 为了避免状态产生哈希冲突,且不想开二维数组,可以将最高位强制或上(1)避免冲突。
概率期望
(5.5) 根据期望的线性性质,一般可以把问题拆成每个独立的决策点被选到的期望之和。
差分前缀和
(5.6) 考虑差分数组对答案的影响是使得某个点到矩阵右下角的正方形全部加某个数,这样可以对差分数组再次进行差分,比如可以维护对角线上的差分数组的差分。
取模
(5.7) 如果要求答案对某个质数取模,而所有可能的质数的成绩比较小,那么可以先将答案对所有可能的质数的乘积取模,最后再对所给的质数取模。
平面距离
(5.8) 切比雪夫距离和曼哈顿距离相互转化时,将平面直角坐标系旋转四十五度。
图论
(2-SAT)
(6.1) 边数过多时,可以考虑用线段树优化连边或者前缀和优化连边。
差分约束
(6.2) 差分约束找到负环后可以根据负环上的信息决定如何调整。