NOIP知识点总结

NOIP知识点总结

基础算法

模拟/搜索

  • 最基础的东西。
  • 没有思路就要打暴力!
  • 写模拟注意思路清晰。
  • 例题:[CSP-S 2023] 结构体,[NOIP2017 提高组] 时间复杂度。应该不会有更难的模拟了吧?

分治

  • 将问题分为子问题,分别解决,然后再合并。
  • 归并排序利用了分治思想。

贪心

  • 需要证明,最好不要乱写。
  • 没有思路的时候可以考虑一下有没有可能是贪心。
  • 例题:[NOIP2012 提高组] 国王游戏。

排序

  • 方法很多,但大部分时候 sort 就够用了。
  • 主要的考察方式可能是排序的内部思想,比如冒泡排序与逆序对。

前缀和 & 差分

  • 比较基本的转化方式,用来进行区间和单点间的转化。
  • 可以上树,能优化很多东西。
  • 能做高维前缀和。
  • 前缀和例题:[NOIP2022] 种花。
  • 差分例题:[NOIP2021] 方差,[NOIP2016 提高组] 天天爱跑步。

二分

  • 常用于求最大/小值最小/大。
  • 将问题转化为判定性问题。
  • 可以用于查找。
  • 例题:[CSP-S 2023] 种树,[NOIP2018 提高组] 赛道修建。

倍增

  • 最知名的应用应该是倍增求 LCA。空间复杂度一般要带 log
  • 例题:[NOIP2012 提高组] 开车旅行。

数据结构

线性结构

  • 包括栈,队列,链表。
  • 支持 O(1) 插入/删除。
  • 单调队列/单调栈就是元素满足单调性的队列/栈。可以在上面二分,或者维护一些信息,如序列中第一个 >ai 的数。有的时候题目本身的性质就满足了单调性,如 [NOIP2016 提高组] 蚯蚓, [CSP-S2020] 贪吃蛇。

哈希

  • 哈希表支持 O(1) 插入/修改,一般使用拉链法实现,也可以使用 map/unordered_map 实现。后面的一般是够用的,除非需要卡常。
  • 可以利用哈希来解决判等问题,如 [NOI2024] 集合,[CSP-S 2023] 消消乐。
  • 可以通过构造一个容易判定的必要不充分条件,利用哈希随机赋权来提高正确率。如 [CSP-S 2022] 星战。

并查集

  • 用于判断两个元素是否属于同一集合。可以用于维护图的连通性等信息。
  • 按秩合并:将大小(深度)的并查集合并到大的并查集上,复杂度 O(logn)。加上路径压缩复杂度是 O(α(n)) 的,其中 α(n) 为反阿克曼函数,可以近似认为是常数。
  • 带权并查集:对于并查集的边定义一定的权值,并且定义其在路径压缩时产生的运算,就可以在并查集中维护一些信息,例如深度/权值等。
  • 扩展域并查集:一个节点可能有很多状态,对于每个状态开一个并查集。如 [NOI2001] 食物链。
  • 可撤销并查集:记录合并时的操作/合并前并查集的权值。不能路径压缩!
  • 并查集能可持久化。

ST 表

  • O(nlogn)O(1) 解决区间最值问题。也可以用于维护一些可重信息,比如 gcd

二叉堆

  • 支持 O(logn) 插入,O(logn) 删除最值,O(1) 查询最大值。一般用 priority_queue 实现,但注意这是大根堆。

左偏树

  • 在二叉堆的基础上支持 O(logn) 合并操作。

树状数组

  • 支持 O(logn) 插入,查询。维护的信息需要满足可减性,例如区间和。
  • 可以维护前/后缀信息,如最值。
  • 相比线段树,优势在常数较小。
  • 树状数组上也可以二分,实现方式类似于倍增。例题:[NOIP2017 提高组] 列队,当然 log2n 也能过。

线段树

  • 应该是 NOIP 以下最难的数据结构。
  • 线段树维护的信息需要可以快速合并,并且满足封闭性(个人理解是不需要引入外部信息来维护线段树内信息)。如区间最值,区间和。
  • 支持 O(logn) 的修改及查询。
  • 线段树信息设计:一般来说,线段树上的信息分为信息(D)与标记(M)。其中 M 是线段树能够保证复杂度的核心。在设计信息时,可以先列出一些必要的信息,再导出更多的必要信息。在考虑信息与标记间转化时,需要考虑 D×DD×MM×M(此处的 × 代表某些神秘操作)。例题:P4314 CPU 监控。

动态开点线段树

  • 由于点数过多,无法先把树建出来,但是需要用到的点较少,因此在用到时开点。空间复杂度 O(QlogV)Q 为操作次数,V 为值域。

可持久化线段树

  • 由于线段树一次只会修改 O(logn) 个节点,我们可以只更新变化的节点,从而保存历史版本。空间复杂度 O(nlogn)
  • 不好 Pushdown,因此可能要改成单点修改或标记永久化。

扫描线

  • 可以维护二维平面上与矩形有关的一些信息,比如矩形大小,面积。实现方法为用一条线从下往上扫,同时将将矩形贡献在下边界插入,上边界删除。

  • 可以标记永久化。

  • 可以将问题抽象到二维平面上,比如把对满足某些条件的 (x,y) 进行修改转成矩形修改操作。

  • 也可以被称为一种思想,在枚举位置的时候加入/删除贡献。

  • 例题:[春季测试 2023] 密码锁。非常难写。

线段树二分

  • 可以在线段树上利用节点本身的权值进行二分,因为线段树的结构本身就很适合二分。

标记永久化

  • 不将标记下放,而是在询问时考虑懒标记。不会带来复杂度的优化。一般会与不好下传标记的线段树配合使用(如可持久化线段树)。

历史和线段树

  • 在维护线段树的过程中维护所有历史版本的和。如 [NOIP2022] 比赛。

线段树合并

  • 支持合并两棵动态开点线段树。一般可以代替启发式合并。
  • 合并 n 棵有一个元素的线段树复杂度为 O(nlogn)。复杂度是均摊的。
  • 可以支持撤销。
  • 真的会考。[NOIP2021] 棋局也干了。

李超线段树

  • 能够维护与线段有关的问题。一般用于斜率优化的维护。

兔队线段树

  • P4198 楼房重建
  • 维护前缀最大值一类的信息,需要单边递归,单次操作复杂度 O(log2n)。如 [省选联考 2024] 最长待机。

其他技巧

  • 可以用矩阵的形式表述线段树上信息的转移。这样会带大常数,可以先用矩阵的方式写出来,再手动去掉无用的状态。

二叉搜索树

  • 是一棵二叉树。
  • 满足一个点的权值大于其左儿子的权值且小于其右儿子的权值。

平衡树

  • 是保证深度为 O(logn) 的二叉搜索树。

  • 支持 O(logn) 插入/删除/查询排名,也可以维护一些其他信息。

  • 可以维护区间信息,如平移/翻转。

  • 本质上是二叉搜索树。

  • NOIP 应该不会考,所以没有深入研究。

笛卡尔树

  • 我们为每个点赋予一对键值 (k,w),令 k 满足二叉搜索树的性质,w 满足堆的限制,那么建出来的就是笛卡尔树。常将数组下标作为 k
  • 可以做到 O(n) 建树。

分块

  • 主要思想:将序列分为若干个块,对于区间修改/查询操作将其分为整块和散块分别处理。
  • 需要平衡复杂度。
  • 例题:[NOI2020] 时代的眼泪,Ynoi 系列的大部分题目。
  • 理论上也不会考。

莫队

  • 将序列分块,以左端点所属块为第一关键字,右端点为第二关键字排序。然后暴力做。
  • 有很多衍生出来的神秘科技,Ynoi 中亦有记载。
  • 理论上更不会考。

图论

BFS/DFS

  • 对图进行遍历。
  • BFS 能 O(n) 地求边权为一的图的单源最短路。
  • dfs 树有一些能够利用的性质,之后会提到。

定义

  • 无向无环图/有 n1 个结点的联通无向图/任意两个结点之间有且仅有一条简单路径的无向图。
  • 也存在有向树。

树的直径/中心/重心

  • 了解求法。直径可以两次 dfs/树形 dp,中心/重心可以记录深度/大小后求。

最近公共祖先 (LCA)

  • 倍增:O(nlogn)O(logn)。可以将倍增数组中小的一维放在前面来卡常。
  • 树剖:O(n)O(logn),常数比倍增小一些。
  • 欧拉序转化为 RMQ:O(nlogn)O(1),用 st 表实现。也可以用 dfs 序,常数小一些。
  • Tarjan+并查集:离线求 LCA,复杂度 O(mα(n))。也可以线性实现。

树链剖分

  • 优雅的暴力。
  • 重链剖分是将按照子树大小划分轻重儿子,长链剖分是按照子树深度。下文的树链剖分默认为重链剖分,因为我没怎么研究长链剖分。
  • 一个点到根的路径上最多只有 logn 条重链。因此,我们可以某些数据结构来维护链上的信息。例如,由于我们可以通过重标号使得一条链的编号连续,就可以利用线段树的数据结构来维护区间信息了。不算线段树复杂度是单次 O(logn) 的。

虚树

  • 适用于树上点很多,但是关键点很少的情况。将所有关键点及两两之间的 LCA 拉出来构建信息,并保存原树上的信息。具体构造过程可以排序后求相邻点之间的 LCA。因此虚树上的点数是 O(n) 的。
  • dp 中也会用到,如 [SDOI2011]消耗战。
  • 应该不会考。

基环树

  • 在树的基础上增加了一条边,从而形成了一个环的图。
  • 突破点一般在环上。
  • 例题:[NOIP2018 提高组] 旅行,[NOIP2023] 三值逻辑。

点分治

  • 对于原问题,我们将其分为经过点 x 和不经过 x 两种情况来考虑。例如,我们要求出是否存在长度为 a 的路径,就可以将路径按照是否经过 x 分类,然后删掉 x,将树分为多个更小的子树考虑。
  • 我们每次挑选出树的重心能使递归层数最少,复杂度(包括遍历)为 O(nlogn)

拓扑排序

  • 只能在有向无环图(DAG)上使用。
  • 每次取出入度为 0 的点,然后更新其所有出边能到达的点的入度。复杂度 O(n)
  • 例题:[NOIP2020] 排水系统。

最小生成树

  • Prim:我们记录每个点与所选点集中的点的最短连边的长度 d,每次取出 d 最小的点,然后利用其更新。复杂度 O(n2),可以在稀疏图中利用堆优化至 O(mlogm)
  • Kruskal:将边按照边权排序,每次试图加入一条新边,若其连接的两个节点属于同一个连通块内,那么加入该边。复杂度 O(mlogm)
  • 例题:[NOIP2013 提高组] 货车运输。

Kruskal 重构树

  • 我们在将两个节点所处连通块合并时,建出一个虚点连到这两个连通块上。
  • 性质:我们将新加入的边的边权作为虚点的点权,那么两个点的 LCA 的点权就是他们在最小生成树上的路径上边权的最大值,并且点到根节点这条路径上的权值单调递增。例题:[NOI2018] 归程。

最短路

  • Floyd:全源最短路,复杂度 O(n3)。非常好写。
  • Dijkstra:单源最短路,复杂度 O(n2)/O(mlogm),后者使用堆优化。是稳定的基于贪心的算法。
  • Bellman-ford:单源最短路。直接将全部边松弛 n 次,复杂度 O(nm)。可以跑负权图,可以判负环。
  • SPFA:Bellman-ford 的队列优化版本,但是复杂度最差仍然是 O(nm)。可以用于判负环,在随机图上表现优秀。关于 SPFA,它死了。
  • Johnson 全源最短路:先跑一遍 Bellman-ford,再重新定义边权,跑 n 轮 Dijkstra。复杂度 O(nmlogm)

差分约束

  • 解形如 xaxby 的不等式组,利用大于关系连边,再跑最短路。
  • 我只打过板子。

同余最短路

  • 可以解决形如"至少要拼几次才能拼出模 mp 的数"的问题。
  • 例如“给定 n 个整数,求这 n 个整数不能拼凑出的最大的整数”。我们以第一个元素为基准,然后在模这个元素的意义下做这个问题。那么,对于大小为 x 的元素,我们可以对 y(x+y)moda1 连边,点 p 的点权为所能拼出的模 a1 意义下为 p 的最小数。跑最短路即可。
  • 你的同余最短路又何必是最短路?可以参考 Alex_wei 大神的“同余最短路的转圈技巧”。

Tarjan

  • 可以用于求强连通分量,点双连通分量/割点/割边,边双连通分量。
  • 注意几种算法代码实现的细微差别。

强连通分量

  • 是有向图中的概念。
  • 缩点之后的图是一张 DAG。
  • 强连通分量的编号是合法拓扑序,在 2-sat 中有用。

点双连通分量

  • 无向图中的概念。

边双连通分量

  • 无向图中的概念。
  • 缩点后是一棵树,这个性质可以使得在对边双缩点后转化为树上问题。如 [NOIP2022] 建造军营。
  • 可以通过边双建出圆方树,但是 NOIP 应该不考。

2-SAT

  • 先建出 2n 个点,分别表示第 i 个点为真/假的情况。我们对于每一种限制将其转化为「A 真/假则 B 真/假」的形式,然后通过连边关系表示推断。我们 Tarjan 缩点后,如果「i 真」和「i 假」在同一个强连通分量内则无解,否则有解。
  • 应选择强连通分量编号较小的,不然可能会出现 A 能推出 B 但 B 不能推出 A 的情况。
  • k-sat 问题在 k3 时属于 NP 完全问题,就是只能暴力的意思。
  • 复杂度 O(n+m),例题 [NOI2016] 网格。

二分图

  • 能分成左右两部分,其中每个部分内部无连边的图。
  • 匈牙利算法:求二分图最大匹配,复杂度 O(nm),其中 m 为边数。
  • 二分图最大匹配利用网络流做,复杂度 O(nm)
  • 需要建模,例题 [CEOI2002] Royal guards。

网络流

  • Dinic 算法复杂度 O(n2m),但是一般不会卡 Dinic。在特殊图上会快很多。
  • 费用流:在求分层图的过程中将 BFS 求深度改为 SPFA 的最短路。
  • 平面图转对偶图:用于网格图等特殊图,可以跑最短路求最小割。例题:[CSP-S 2021] 交通规划,[ICPC-Beijing 2006] 狼抓兔子。
  • 网络流侧重于建模。
  • 应该不考。

线段树分治

  • 离线,将删边转变为加边,代价是多一个 log
  • 一般配合可撤销并查集使用。记得不要路径压缩。

其他技巧

  • 优化建图:有线段树优化建图/前后缀优化建图/分块优化建图等等技巧,最核心的思想是建出连向一部分点的虚点,从而达到区间连边的效果。

动态规划

性质

  • 最优子结构
  • 无后效性
  • 子问题重叠

记忆化搜索

  • 要打记忆化搜索嘞!
  • 一般来说是先打一个搜索,然后发现有很多重复访问的状态,就把这些状态记忆下来。
  • 可以搭配 map 使用。
  • 在直接转移过于困难是可以记忆化搜索,如 [NOIP2017 提高组] 逛公园。
  • 在有很多冗余状态的情况下也可以记忆化,如 [AGC020E] Encoding Subsets。
  • 用记忆化搜索实现数位 dp 非常方便。

背包 DP

0-1 背包

  • 物品只能拿一次,有代价 wi 与价值 vi
  • 有转移 max(fi,fiwi+vi)fi
  • 也有计数类型的 0-1 背包,转移为 fi+fiwifi
  • 注意转移顺序,是从大到小
  • 背包的状态与物品顺序无关,因此计数背包是可撤销的。这里的可撤销不仅仅是 0-1 背包,完全背包也可以。

完全背包

  • 物品可以拿无限次。
  • 转移方程同上,转移顺序是从小到大
  • 例题:[NOIP2014 提高组] 飞扬的小鸟。

多重背包

  • ki 个物品。
  • 二进制拆分优化:将一个物品拆成 1,2,4 为一组,转化为有 O(nlogk) 个物品的 0-1 背包。
  • 单调队列优化:将 dp 数组按照 modwi 的值分为 wi 组,对每一组进行单调队列优化 dp。

分组背包

  • 每个组中选一件物品。
  • 对每个组做一次 0-1 背包即可。

树形依赖背包

  • 物品之间有依赖关系。
  • 把一个物品和所有被其依赖的物品放到一起,对每一棵树做分组背包。
  • 例题:[NOIP2006 提高组] 金明的预算方案。

区间dp

  • 将问题转化成每个区间中的子问题,对每个区间求解。
  • 转移方程的形式一般为 fi,j=maxk=ij{fi,k+fk+1,j+val}
  • 例题:[NOIP2003 提高组] 加分二叉树,[CSP-S 2021] 括号序列。

树形 DP

树上背包

  • 在树上做背包。不是树形依赖背包。
  • 朴素实现复杂度 O(nk2),用子树 siz 精细实现后复杂度 O(nk),其中 k 代表背包容量。

换根 dp

  • 先做一遍暴力的树形 dp 算出根位置的答案,再考虑将其某一个儿子作为根会对答案产生什么影响。

状压 DP

  • 状态总数不是很多,一般为 O(2n) 的级别,n 很小。
  • 将状态压缩为整数,通过枚举集合来进行转移。例题:[NOIP2017 提高组] 宝藏,[NOI2001]炮兵阵地。
  • 子集枚举的复杂度为 O(3n)
  • 可能需要钦定转移顺序来方便转移,优化复杂度。比如钦定必须要转移到当前状态中的第一个 1 之类的。如 [NOIP2016 提高组] 愤怒的小鸟。
  • 不一定会直接把状压的东西非常明显地写出来,而是隐藏在一个比较大的数据范围内。如 经典的 [NOI2015]寿司晚宴。

数位 DP

  • 对数字进行 dp。
  • 是计数类型的 dp,通常表现为对满足某个条件且 x 的数字计数。
  • 我喜欢使用记忆化搜索实现。
  • 例题: [NOIP2021] 数列。

动态 dp

  • 也叫 ddp。一般在树上实现。
  • 将链分为重链和轻链,将转移用矩阵写出来,用线段树维护区间矩阵乘积。查询树剖即可。对于修改,我们将转移分为从重儿子转移和从轻儿子转移,重儿子的转移写到矩阵中不用修改,轻儿子暴力改。这样复杂度是 O(log2n) 的,可以做到 O(logn),但是前者一般够用。
  • 例题:[NOIP2018 提高组] 保卫王国,[CSP-S 2022] 数据传输。

dp 优化

  • 方式很多。

单调队列优化

  • 一个人要是比你小,还比你强,那你就永远打不过他了。

  • 对于点 x,如果能找到一个点比它更优且能覆盖更多转移,那么肯定可以弹出 x

  • 加入元素时,弹出队首过时决策,弹出队尾不优决策,从而维护单调性。

  • 这里的队列是 deque,即双向队列。

  • 例题:[CSP-S2019] 划分。

斜率优化

  • 将转移方程写成 YjYiXiXj 的形式,然后维护凸包。

  • 存在 aiaj 这一类项时,不能用单调队列,可以考虑斜率优化。

  • 例题: [HNOI2008] 玩具装箱。

  • 大概率不会考。

slope trick

  • 画出 dp 图像,大概率能用归纳法证明 dp 值的图像是一个凸包。

  • 分析转移造成的影响,想办法维护图像,比如可以用 multiset 记录斜率的变化点。

  • 说到凸包顺便说一下,其实应该不能考。

四边形不等式

  • 对于形式为 fi,j=min{fk,j1+val(k+1,i)},k[0,i) 的 dp,如果满足 val(l,r)+val(l+1,r)val(l,r)+val(l+1,r+1),则称其满足四边形不等式。
  • 能通过四边形不等式推出 dp 数组的转移点具有单调性,可以通过分治,直接利用单调性等方式进行优化。
  • 也可以打表猜单调性。

数据结构优化dp

  • 种类很多,需要根据具体情况选择合适的数据结构维护合适的东西。
  • [CSP-S 2024] 染色 前缀和优化 dp。
  • [NOIP2023] 天天爱打卡 线段树优化 dp。

矩阵加速

  • 如果转移有大段的相同,可以考虑将转移用矩阵的方式写出来,然后通过矩阵快速幂得到最终的 dp 值。
  • 广义矩阵快速幂可以解决最优化问题,即 ci,j=max{ai,k+bk,j}
  • 可以通过矩阵乘向量把复杂度从 O(Qlog3n) 优化到 O(log3n+Qlog2n)。例题:[NOI2020] 美食家。

其他

  • 容斥原理:可以考虑容斥原理优化 dp。例题:[CSP-S2019] Emiya 家今天的饭,[省选联考 2022] 卡牌。
  • 猜结论:很多 dp 不能直接做,需要通过猜一些结论来得到题目的性质/充要条件,从而转化为更好 dp 的形式。如 [春季测试 2023] 圣诞树,[NOIP2021] 方差。

字符串

字符串哈希

  • 哈希的一种方式。
  • 可能会被卡,如果时间充裕可以写双模数哈希。
  • 二分+哈希可以用来替代 Manacher,当然后者也不难写。

字典树(trie)

  • 可以用来查找一个字符串是否出现过。
  • 是 AC 自动机的一部分。
  • 01 trie 可以用来解决异或相关问题,如 [省选联考 2024] 魔法手杖。

KMP

  • 可以 O(n) 求出 border,构建单字符串的 fail 树。
  • 可以通过 fail 树加速匹配,复杂度 O(|S|+|T|)
  • 思想是在通过 fail 树加速的基础上,自己与自己进行匹配,从而一边构建 fail 树一边利用。

扩展 KMP(z 函数)

  • O(n) 计算 s 的每个后缀与 slcp 长度。
  • 思想是通过前面已经算出的部分来加速处理后面的部分,复杂度是均摊的。
  • 感觉像是 KMP+Manacher。
  • 例题:[NOIP2020] 字符串匹配,当然只是这题中的一部分。

AC 自动机(ACAM)

  • 不是自动 AC 机。
  • Trie+KMP:现将所有模式串建成一棵 trie 树,然后处理出每个节点的失配指针。
  • 能够解决多模式串匹配问题,复杂度 O(|S|+|||T|)|| 是字符集大小。
  • 优化:在匹配时不是一直跳 fail,而是利用拓扑排序在最后一起更新。
  • ACAM 上 dp:可以在通过 AC 自动机的节点进行字符串 dp,甚至还可以套上矩阵优化。

Manacher

  • O(n) 处理回文串。
  • 思想是利用之前算出的信息加速计算,处理出 1i1 作为回文中心时最远的右端点,然后将对称的点的最长回文串长作为初值。
  • Manacher 处理的是奇回文串,所以需要在相邻字符之间插入一个神秘字符,如 '#'。
  • 通过对 Manacher 复杂度的分析,能发现字符串中本质不同的回文串只有 O(n) 个。

其他

  • 总长为 n 的一组字符串,其中本质不同的串长只有 O(n) 种。
  • NOIP 考字符串真的考得很少。

数学

位运算

  • 初赛喜欢考(
  • 计算机的底层逻辑,卡常效果显著。

快速幂

  • O(logy) 计算 xy。利用了倍增思想。

数论

辗转相除法

  • O(logn)gcd(x,y)

质数

  • 能够 O(n) 判断一个数是不是质数。
  • 有更厉害的方法,但我不会。
  • 可以线性筛判断 [1n] 之内的数是不是质数。线性筛也可以筛欧拉函数,莫比乌斯函数。

数论分块

  • 对于形如 i=1nf(i)g(ni) 的式子,如果可以 O(1) 计算 i=lrfi,那么就可以 O(n) 计算上式。

裴蜀定理

  • 关于 xy 的同余方程 ax+byc 的充要条件是 gcd(a,b)|c

逆元

  • mPrime 时,有 a·am21(modm)
  • 扩展欧几里得:对于 ax+by=1,我们求出 bx+(amodb)y=1 的解,那么 x=y,y=xaby 是一组合法解,递归即可。
  • 线性求逆元:对于 1!,2!,3!n! 的逆元,我们求出 n! 的逆元,然后 inv(i!)=inv((i+1)!)×(i+1)
  • inv(i)=(mmiinv(mmodi))modm

中国剩余定理(CRT)

  • 解方程组 {xa1(modm1)xa2(modm2)    xan(modmn),保证 m1,m2mn 互质。
  • 先计算所有模数的积 m,对于每个方程,算出 bi=mmi,并算出其在模 m 意义下的逆元 bi1,再计算 ci=bibi1(不取模)。x=i=1naicimodn 为一组合法解。

扩展中国剩余定理(exCRT)

  • 对于方程组 {xa1(modm1)xa2(modm2),将其转化为不定方程 {x=m1p+a1x=m2p+a2,有 m1pm2p=a2a1,扩欧求解即可。

欧拉函数

  • 记作 φ(n),含义是 i=1n[gcd(i,n)=1]
  • n=i=1spiki,且 pi 为质数,那么有 φ(n)=n×i=1spi1pi
  • 欧拉函数是积性函数,即对于 gcd(a,b)=1,有 φ(ab)=φ(a)φ(b)
  • 欧拉反演:n=i|nφ(i)

欧拉定理

  • gcd(a,m)=1,那么 aφ(m)1(modm)

扩展欧拉定理

  • ab{abmodφ(m)gcd(a,m)=1abgcd(a,m)1,b<φ(m)a(bmodφ(m))+φ(m)gcd(a,m)1,bφ(m)(modm)
  • 对于幂塔(即形如 cccc 的东西),可以利用扩欧证明其在 O(logn) 层后值就不变了。例题:[六省联考 2017] 相逢是问候。

莫比乌斯函数

  • μ(n)={1n=10x2|n,xN(1)kelse,n=i=1kpi,piPrime
  • 莫比乌斯函数是积性函数。
  • 莫比乌斯反演:d|nμ(d)={1n=10n1

组合数学

排列组合

  • Amn 表示从 n 个数中选 m 的排列数,有 Amn=n!(nm)!
  • Cmn 表示从 n 个数中选 m 的组合数,有 Cmn=n!(nm)!m!。也记作 (nm)

Lucas 定理

  • (nm)modp=(n/pm/p)·(nmodpmmodp)modp,pPrime

容斥原理

  • i=1nai∣=T[1,n]N(1)|T|1iTai

错排

  • Dn=Dn1+Dn2
  • Dn=nDn1+(1)n

卡特兰数

  • Hn=(2nn)(2nn1)
  • Hn=Hn1(4n2)n+1

线性代数

  • 写了一些用的比较多的东西。

矩阵乘法

  • Ci,j=k=1nAi,k+Bk,j
  • 广义矩阵乘法:就是把上面的 + 换成别的东西。需要验证其是否合法,比如 (max,+) 就是合法的。
  • 满足结合律,不满足交换律
  • 可以解决递推问题,也可以解决一些图上的问题,比如定长的权值最大路径。

线性基

  • 一般是异或意义下的线性基。
  • 可以在线性基上贪心,比如说求出一组数的最大异或和。
  • 构建方法有贪心法和高斯消元法,后者构建出来的线性基性质好一些。
  • 支持 O(logn) 插入,O(logn) 查询,O(log2n) 合并。应该不支持删除。

高斯消元

  • O(n3) 解方程组。感觉是很符合思考习惯的算法。

矩阵求逆

  • 在原矩阵旁边放一个单位矩阵,对原矩阵进行高斯-约旦消元,消元后右边的就是逆矩阵了。

博弈论-公平组合游戏

  • 没有写其他博弈论的内容,因为我不会。

Nim 游戏

  • n 堆石子,每堆 ai 个,取最后一个石子的人赢。
  • Nim 和:a1xora2xora3xoran。如果 Nim 和为 0 那么先手输,否则先手赢。

有向图游戏

  • 大部分的公平组合游戏都可以转换为有向图游戏。

SG 函数

  • mex 函数:mex{S}=min{x},xS,xN
  • 将游戏在有向图上考虑。设 y1,y2ykx 的全部后继状态,有 SGx=mex{SGy1,SGy2,,SGyk}
  • 对于由 n 个有向图游戏组成的组合游戏,我们设起点分别为 s1,s2,sn,那么这个组合游戏的起点的 SG 值为 SGs1xorSGs2xorSGs3xorSGsn
  • 当且仅当一个状态的 SG 值不为 0 时,先手必胜。

杂项

离散化

  • 减小值域范围,很多时候是题目的第一步转化。
  • sort+unique+lower_bound 三件套离散化。

高精度

  • 朴素实现是加减法 O(n),乘 O(n2)。高精除低精 O(n2)
  • 例题:[NOIP2020] 排水系统,[NOIP2012 提高组] 国王游戏。

双指针

  • 利用单调性,通过两个指针的移动来维护信息。
  • 例题: [NOI2024] 集合。

0/1分数规划

  • 一般是在外面套一层二分,然后转化为判定性问题。
  • 例题:[HNOI2009] 最小圈。

珂朵莉树/颜色段均摊

  • 用 set/list 来维护颜色段。
  • 复杂度基于数据。随机数据下复杂度是对的。

CDQ 分治

  • 利用分治计算前一半对后一半的影响。本身复杂度是 O(nlogn) 的,不过一般要套数据结构。
  • 有很严格的偏序关系限制。

随机化

  • 用于最优化问题。
  • 随机选择一个序列/点之类的东西,然后转化为判定问题。通过多次的随机选择一个比较优的解。
  • 在某些时候正确性是有保证的,比如随机个 40 次,那么有点落在重心子树内的概率很大。
  • 不要以随机化为第一选择,在时间充裕,拿完该拿的分之后再做考虑。
  • 例题:[春季测试 2023] 密码锁,随机化有 95pts。

模拟退火/爬山

  • 区别在于模拟退火以较低概率接受劣解,概率随时间降低。爬山则是只接受更优解。
  • NOIP 中感觉不是很实用,谨慎选择。
  • 例题:[NOIP2021] 方差。
posted @   LiuLianLL  阅读(325)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!
点击右上角即可分享
微信分享提示