一些自己看的OI小知识

  1. 判断某个数能否由一些数组成可以先对数进行排序然后使用设 \(f_x\) 表示 \(x\) 是否能被组成,然后对于前 \(i\) 个数就有 \(f_x=f_x | f_{x-a_i}\) ,具体题目是 \(noip2018\) \(day1t2\)

  2. 你去删除一个元素的时候可以不用说去真正的移除,你可以用一个并查集来标记像后方,表示被移除。并查集进行打标记是一个很有用的思路。

  3. 实在遇到不会做的题,考虑一下 dp,即使不是正解也绝对没错,如果是在树上做 dp ,不要但考虑在链上的不如直接考虑树上 dp。

  4. 遇到要求问方案数,没事就容斥一下,说不定就弄出来了。

  5. 求某个节点在某个方向上的直接儿子,改为求方向上节点 \(v\)\(dep_v-dep_u-1\) 级祖先

  6. \(\sum_{i=1}^n i^2 = \dfrac{n(n+1)(2n+1)}{6}\)

  7. 裴蜀定理同样适用于多元,\(ax+by+cd=t\) 要求 \(t|(a,b,c)\)

  8. 判断 \(x\) 是否为 \(y\) 的 祖先,可以记录 dfs 序进行判断,看一下对于 \(x\)\(dfs\) 序区间是否包含 \(y\) 就行了。

  9. 二项式反演:考虑求恰好 \(k\) 个物品的时候,可以按下面两种方法来做。

    \(f_i\) 表示至少 \(i\) 个物品时的答案, \(g_i\) 为恰好 \(i\) 个物品时的答案。

    然后 \(f_k=\sum\limits_{i=k}^n\displaystyle\binom{i}{k}g_i\)

    紧接着 \(g_k=\sum\limits_{i=k}^n(-1)^{i-k}\displaystyle\binom{i}{k}f_i\)

    \(f_i\) 表示至多 \(i\) 个物品时的答案, \(g_i\) 为恰好 \(i\) 个物品时的答案。

    然后 \(f_k=\sum\limits_{i=0}^k\displaystyle\binom{k}{i}g_i\)

    紧接着 \(g_k=\sum_{i=0}^k(-1)^{k-i}\displaystyle\binom{k}{i}f_i\)

  10. 在使用全排列 \(\text{STL}\) 之前记得将序列从小到大排序。

  11. 对于树链剖分上的东西,一个点到他的父亲,最多只会经过 \(\text{log}\) 条轻边,有时可以根据这个,用数据结构维护重链的操作,轻链上的进行暴力,复杂度仍然是对的。

  12. 多测学会清空。

  13. 遇到区间整体加同一个数多次别去想着直接上数据结构,想想差分,如果差分后仍然数量比较多,不妨想想将差分后的序列再差分,最后只需要做两次前缀和就可以了。

  14. \(1 \sim n\) 组成排列考虑分成 \(\sqrt{n}\) 块, 每一块分别输出,不断减小 \(m\) ,可以证明是对的,也就是 CF1017C 。

  15. 异或相关,考虑使用线性基或者 01 trie 。

  16. 树上限制构造次数或者明确遍历次数为 \(n \log n\) 的时候,考虑轻重链剖分,保留重儿子答案,单独处理轻儿子。

  17. 哈夫曼树。

  18. 如果一堆字符串保证 \(\sum len \le n\) 的话,那么字符串长度不一样的只会有 \(\sqrt{n}\) 种,可以根据这个进行根号分治,长度小于根号的存下来后面一起暴力,大于根号的直接暴力。

  19. unordered_map 会对一类特殊的数字被卡,也就是 \(2^{16}\)

  20. 遇到对每个东西有两种选择,选每种选择有代价,求最小代价,于是考虑拆点之后跑最短路

  21. 平面图转对偶图,就是把区域当成一个点,然后建图,可以看狼抓兔子那道题。

  22. 一棵树只会有 \(\sqrt{n}\) 种不同的度数

  23. 求一些点所构成的极小连通子树或图的边权和,可以将点按 \(dfs\) 序排序,然后为 \(\{a_1, a_2, a_3, \dots ,a_k\}\) 则边权和的两倍为 \(dis(a_1,a_2) + dis(a_2, a_3) + \dots + dis(a_n, a_1)\)

  24. 看到限制条件考虑 2-sat

  25. 和距离有关考虑树分治,也可以考虑长剖进行求解

  26. 没事多考虑建边,如果建边数量太多,考虑优化建边,如果 \(A\), \(B\), \(C\)\(A\)\(B,C\) 建边,然后 \(B\)\(C\) 建边,那么考虑建 \(A->B->C\)

  27. 对于 \(\max\) 这类不方便直接做的东西,考虑拆开,假设里面某一个为更大,然后下去做。

  28. 一种 \(dp\) 状态的设立 \(dp_i\) 表示以 \(i\) 结尾的不合法/合法的数量。

  29. 在设计一个数据结构时,需要保证:

  • 数据组织成严格的树结构:维护信息的结构有父子关系,在访问子结构时,必须访问父结构。
  • 每个节点上维护的信息不相互包含,父子结构上的标记有严格的时间顺序。如 sone1 中,设计虚子树修改标记和实子树修改标记,而不包括总子树修改标记;维护虚子树信息和和实子树信息和,但不维护总子树信息和。

不是我说的。

  1. 两个点之间整点数量为 \(\gcd(|x1-x2|,|y1-y2|) + 1\) LOJ1077

  2. 在不强制在线情况下分块一定比莫队弱。

  3. 线段树合并在对一类特定问题下可以做到空间 On

  4. 对于棋盘类问题,关注是否有一种可能,每行或者每列的问题独立。

  5. 期望概率等高斯消元想到之后,看看是不是树的形态,如果是,那么爽死了,直接列成 \(f_u=k_u \times f_{fa}+b_u\) 然后维护 \(k\)\(b\) 最后代入根节点的值解即可。

  6. 期望的线性性质时刻关注

  7. \(\phi(ij) = \dfrac{\phi(i)\phi(j)(i,j)}{\phi((i,j))}\)

  8. 时刻记住自然根号的存在啊

  9. 周期引理:若某个串存在两个 period \(a,b\),有 \(a+b\le n+\gcd(a,b)\),则 \(\gcd(a,b)\)\(n\)​ 的 period, 证明看我写的 [ZJOI2017]字符串 的题解。

  10. 学会分治。

  11. 反悔贪心,人类智慧,做题先考虑贪心,贪心不会再 dp (

  12. \(1 \ \text{xor}\ 2 \ \text{xor}\ 3 \ \text{xor}\ \cdots \ \text{xor}\ n=\begin{cases}1,n\bmod4=1\\n+1,n\bmod4=2\\0,n\bmod4=3\\n,n\bmod4=0\\\end{cases}\)。归纳证明。

  13. 对于中位数,可以将比他小的数设为 \(-1\),比他大的数设为 \(1\),然后剩下的数和为 \(0\) 的话,那么这个树是中位数。

  14. 一个有 \(m\) 条割边的无向联通图,等价于缩点之后是一棵 \(m+ 1\) 个节点的树。

  15. \(\mu(ij) = \mu(i) \mu(j) \mu(\gcd(i,j))^2\)

  16. 树上问题需要牢记从下往上做,如果做了一次没有做完,那就再从上往下做回来

  17. 对于线段树上,维护 lcm 的复杂度并不是 \(\log n \log V\),而是 \(\log n + \log V\),可以证明。

  18. \(n\) 通过一些操作,构造出 \(2^k\),考虑在 \([n, 2n)\) 中取找出这个范围的数。

  19. 一团东西很复杂,那就让这些东西彼此独立,将贡献分开来,最后考虑将答案给合并。

  20. 图上与边相关问题,可以通过缩边双成为一棵树,图上与点相关问题,也可以通过缩点形成一棵树!

  21. 一种交互题,\(n\) 个柱子排成环形,每次移动一个柱子上的数到下一个柱子上,假如每个柱子上都是 \(1 \sim n\) 的颜色各一种,那么让第 \(i\) 个柱子上全是 \(i\) 的操作只用 \(\dfrac{n \times (n - 1)}{2}\)

  22. 方差 \(Var(x)=E(x^2)-E(x)\)

  23. Matrix-Tree 定理可以快速求出所有生成树边权乘积的和,其方法是将一条权值为 \(w\) 的边拆为 \(w\) 条重边,此时生成树个数即为所求。运用 Matrix-Tree 定理求行列式即可。若需求所有生成树边权和,可将一条权值为 \(w\) 的边的权值视为多项式 \(wx+1\),运用上述方法求得的一次项系数即为所求,因此我们做多项式乘法时对 \(x^2\) 取模即可。

  24. 遇到与 lowbit,highbit 等有关的问题时,不妨用 trie 树来维护数据,可能会起到奇效。

  25. 如果直接做树上问题不好做,又需要其父子信息,不妨将其建出点分树,此时其深度为 \(\log\)​,所以直接记每个祖先的信息即可。如“没有上司的舞会”一类问题可以直接按照 dfs 序 dp,记录一下每个点的 \(1\sim\log\)​​ 级祖先是否被选择,这一维是 \(2^{\log}=n\) 级别的,适用于 \(n\)​​​ 小而另一位巨大的时候。这条性质正确的原因是,原树上的父子在点分树上必然是子孙。

  26. 学会用哈希:CF1622F。质因数/每个数随意赋值,乘/加法转异或是一种很常用的套路,本质就是哈希。

  27. 子集哈希之类的,随机化乱搞

  28. kdt 好啊,遇到懒得写矩形分讨扫描线的时候可以直接 kdt,最后比正解快了 3 倍,而且无脑。

  29. 一个序列,其中每个元素等概率随机为 1/-1,其前缀和绝对值最大值期望是 \(O(\sqrt n)\) 的。

  30. 在对一个数列计算每种元素的个数时,不仅可以用 map 或桶等东西计数,也可以直接将其排一遍序,然后直接扫一遍。

  31. 遇到需要维护一堆数求 min 的结果并且某些数会增大的类似问题中,不妨考虑将原问题倒着做,将加变成减,这样不需要将原来的贡献剔除。

  32. 求一个序列的本质不同子序列数目,我们可以考虑 dp。
    https://www.cnblogs.com/ptno/p/16541669.html

  33. 区间 dp 的四边形不等式优化,如果满足四边形不等式,那么记录决策点,则 \([l,r]\) 的决策点在 \(w(l, r- 1) \sim w(l + 1, r)\)

  34. 如果是形如 \(dp_{i,j} = \sum_{1 \leq k \leq j} dp_{i-1,k} + w(k,i)\) 的时候。

    也有可能满足四边形不等式,\(w(i,j)\)\(w(i - 1, j),w(i, j+ 1)\) 之间。

    于是进行第二维的时候我们要逆序的啦!

  35. 图的最大团等于补图的最大独立集。

  36. 二分图最大独立集=二分图顶点数-最大匹配

  37. 每个点的度数都是奇数,等价于这个图中只存在大小为偶数的连通块

  38. 假如有 \(n\) 个任务,每个任务有一段区间,然后总共 \(n\) 秒,每秒只能执行一个任务,那么这东西可以贪心。

    \([l,r]\) 先按左端点升序排序,然后假设当前是第 \(i\) 秒每次加入当前能加入的区间,把这些区间用优先队列维护,按 \(r\) 升序排序,\(r\) 小的先做,就好了。

  39. 曼哈顿距离为 \(|x1-x2| + |y1-y2|\)

切比雪夫距离为 \(\max(|x1-x2|,|y1-y2|)\)

一个点 \((x,y)\) 的坐标变为 \((x+y,x-y)\) 后,原坐标系中曼哈顿距离 \(=\) 新坐标系中切比雪夫距离。

一个点 \((x,y)\) 的坐标变为 \((\dfrac{x+y}{2},\dfrac{x-y}{2})\) 后,原坐标系中的切比雪夫距离为新坐标系中的曼哈顿距离。

  1. 我们遇到逆序对的时候,要求期望逆序对数,可以把逆序对数分开然后求对期望的贡献再求和

  2. 一种合法的BFS序的划分对应一棵树

  3. meet in the middle 的时候算左边算出来对右边的一部分有限制,考虑将限制对应到

  4. 假如有重复调用某个区间,然后要求执行完这些操作之后的最终序列,可以倒着过来然后用 ds 往前处理出每个操作的次数,然后在对于某个操作单独处理。

  5. trie查询一个数与集合中的数按位xor,and,or 最大值。
    按位 xor 就是经典的倒着建,然后能走就走。
    然后对于and和or,考虑从高位到低位的贪心,如果这一位是 \(1\),那么必须走 \(1\),否则 \(01\) 都可以走。

    那么每次插入的时候可以打标记,比如这样:

    void get(int x) {
      if(vis[x]) return;
      vis[x] = 1;
      for(int i = 19; ~i; i--) {
    	if( (x >> i) & 1 && !vis[x ^ (1 << i)]) {
    	  get(x ^ (1 << i));
    	}
      }
    }
    

    然后二进制下某几位为 \(1\) 的情况是有可能的,这样记忆化之后,打标记的复杂度就是 \(O(V)\) 的了。

    然后查询的时候就直接维护一个 \(p\),如果这一位必须是 \(1\),就看前几位加上自己是 \(1\),有没有可能,如果可能就把这一位变成 \(1\),否则不管。

  6. \(\varphi(i^j)=\varphi(i)\times i^{j-1}\)

  7. 将选中位数和平均数之类的操作看成上树,然后新建节点表示选出来的数,并让他为其他数的父亲,然后在树上进行 dp 之类的

  8. 括号序列在维护形如“树上满足条件的两点距离最大值” 这样的问题中非常好用,注意我们使用的括号序列中间是有数字的,我们断开的时候只从合法的数字处断开,这是为了方便限制。
    首先明确一个性质,树上两点间距离等于其间无法匹配的括号的数量
    那么我们对于一个节点,设 \(a\) 代表左括号个数,\(b\) 代表右括号个数,维护前缀/后缀的 \(a + b/a - b\) 最大值就可以用线段树维护了。https://www.luogu.com.cn/blog/user13183/solution-p2056

  9. 网络流退流,每次有加边减边的时候,假设是 \((u,v)\) 被删去,那么以 \(u\) 为源点,向 \(S\) 跑一次最大流即可,再以 \(T\) 为源点,然后向 \(v\) 跑一次最大流即可(费用流是一样的)。

  10. 有一些点,一些有向边,求最少加多少边使得任意两个点可互相到达了。答案为:求出所有的分量,缩点,分别求出出度和入度为 \(0\) 的点的数量,取多的为答案、

  11. 边双中的任意两个点之间至少有两条边不重复的路径,边双缩点后是一棵森林。

  12. 点双中任意两个点之间至少有两条点不重复的路径(除了只有两个点的点双)。

  13. 最大权独立集=总权值-最小点覆盖
    最大独立集=反图的最小点覆盖

  14. 平衡树内部无论怎么旋转,中序遍历不变。

  15. 假如 dp 优化实在不会做,但是转移 dp 要满足某些条件,尝试在线段树上爆搜,然后剪枝。

  16. 冒泡排序的次数等于逆序对数目

  17. \(1,1,2,5,14,42,132\) 是卡特兰数的前几项,打表。

  18. 遇到分割的,互相包含的区间类问题,考虑建成树来做。

  19. 给定一棵树和很多条链,每个链有一个价值,要求选一些不相交的链使价值和最大是个经典问题,hdu5293。当选点 \(x\) 的链的时候,答案为 \(sum_{to} + val + \sum_{v} sum_v - f_v\)

  20. 树上点边容斥,森林连通块数量 = 点数-边数

  21. 线段树合并,\(f'_{u,t}=\max\{f_{u,t}+\max_{1\le i\le t}{f_{v,i}},f_{v,t}+\max_{1\le i\le t}{f_{u,i}}\}\) 这样的形式,你可以考虑线段树合并,这个其实并不难,按照从左到右线段树合并,同时维护一下前缀最值,然后往右合并即可。

  22. 要求求某个数 \(\geq n\) 的方案数,不妨记录 \(dp_k\) 表示还要 \(\times k\) 才能大于等于 \(n\) 的方案数,这样类似整除分块,不同的 \(k\) 只会有根号个。

  23. 一个模型,很多个长度为根号的木棍,每次可以在最前面加入一根,或者把所有已经加入的木棍的长度全部加 \(1\),设 \(g_{i,j}\) 表示选了 \(i\) 根木棍,总长度为 \(j\) 的方案数,那么有如下 dp:\(g_{i,j} = g_{i-1,j-\sqrt{n}} + g_{i,j-i}\)

  24. 树上的连通块问题,在 dfn 序上 dp 可以做到单点加入。https://www.cnblogs.com/chihik/p/16779449.html

  25. ![[Pasted image 20221017212339.png]]

  26. 将一个序列剖成若干个单调不升子序列的最小个数等于该序列最长上升子序列的个数(dilworth 定理)

  27. 要求原序列严格递增的套路是,令 \(a_i = a_i - i\),这样严格递增变成了严格不下降。

  28. 一个合法的括号序列中任何一个前缀的左括号数量都要大于等于右括号

  29. 一个 \(1 \sim n\) 的排列的逆序对的期望为 \(\dfrac{n \times (n - 1)}{4}\)

  30. 判断集合每个数只出现一次可以进行随机化哈希,给每个数赋值一个随机权值,然后判断所有数的和是否等于集合中数的权值和。

  31. 判断组合数的奇偶性,但 \(\dbinom{n}{k}\)\(n \& k = k\) 的时候就是奇数,否则为偶数

  32. \(F(n, m) = \sum_{i=0}^m \dbinom{n}{i}\),那么 \(F(n, m) = F(n, m - 1) + \dbinom{n}{m}, F(n, m) = 2 \times F(n - 1, m) - \dbinom{n-1}{m}\)。又由于组合数中 \(m \leq n\) 才有贡献,于是多组询问的时候可以把 \(m\) 当成 \(l\)\(n\) 当成 \(r\) 跑莫队。

  33. 对于网格图上,假如限制是在同一行,或者同一列的点 \((x, y)\) 之间的,那么你考虑对每一行,每一列单独建 \(n + m\) 个点,\((x, y)\) 被转化成行点 \(x\) 到列点 \(y\) 的边。

  34. 欧拉回路辅助边的定向,假如要求出度等于入度,那么直接跑欧拉回路就行,假如要求出度于入度差一,考虑能否规约到上面出度等于入度的情况,建一个虚拟节点,让他们之间连边即可。

  35. 假如存在各种对区间进行赋值为区间内最小值的操作,然后问最后能够得到多少种不同的区间,不妨考虑设计状态 \(f_{i,j}\) 表示只使用 \(1 \sim i\),构造出了一个长度为 \(j\) 的结果序列的方案数,考虑转移的时候美剧一个数 \(a_i\) 的极大扩展区间,那么写出转移 \(\forall j\in [l,r],\qquad f(i+1,j) = \sum_{k=l-1}^j f(i,k)\)

  36. 计算 \([1, m]\) 中与 \(n\)\(\gcd\)\(i\) 的数量,https://www.luogu.com.cn/blog/dottle/ji-suan-yu-n-zui-tai-gong-yue-shuo-yi-ding-di-shuo-di-shuo-liang

  37. 一颗二叉树的中序遍历其实对应一种出入栈序列,也就是卡特兰数。

  38. 一个联通的 DAG 添加最少的边使得其强连通,最少的边数为 \(\max ( 0 入度点,0 出度点)\)

posted @ 2021-11-10 21:56  Pitiless0514  阅读(691)  评论(9编辑  收藏  举报