前言
本文主要总结常见算法与数据的功能。
正文
基础
1. 前缀和
题面关键词:区间询问
算法功能:预处理后O(1)输出区间答案
例题1:输入一个长度为 n 的整数序列。接下来再输入 m 个询问,每个询问输入一对 l,r。对于每个询问,输出原序列中从第 l 个数到第 r 个数的和。
例题2:输入一个 n 行 m 列的整数矩阵,再输入 q 个询问,每个询问包含四个整数 x1,y1,x2,y2,表示一个子矩阵的左上角坐标和右下角坐标。对于每个询问输出子矩阵中所有数的和。
2.差分
题面关键词:区间询问、静态区间加减
算法功能:配合前缀和O(1)对某一区间实现加减操作
例题1:输入一个长度为 n 的整数序列。接下来输入 m 个操作,每个操作包含三个整数 l,r,c,表示将序列中 [l,r] 之间的每个数加上 c。请你输出进行完所有操作后的序列。
例题2:输入一个 n 行 m 列的整数矩阵,再输入 q 个操作,每个操作包含五个整数 x1,y1,x2,y2,c,其中 (x1,y1) 和 (x2,y2) 表示一个子矩阵的左上角坐标和右下角坐标。每个操作都要将选中的子矩阵中的每个元素的值加上 c。请你将进行完所有操作后的矩阵输出。
3.二分
题面关键词:最小值最大、最大值最小、不大于某数的最大值、大于某数最小值
算法功能:1.在有序序列中O(logN)找到某数 2.优化枚举答案
例题1:给定一个按照升序排列的长度为 n 的整数数组,以及 q 个查询。对于每个查询,返回一个元素 k 的起始位置和终止位置(位置从 0 开始计数)。如果数组中不存在该元素,则返回 -1 -1。
例题2:给定一个浮点数 n,求它的三次方根。
数据结构
1.哈希表
算法功能:快速输出映射关系(某数是否出现过)
1.map
2.set
例题1:维护一个集合,支持如下几种操作:I x,插入一个数 x;Q x,询问数 x 是否在集合中出现过;
2.堆、优先队列
算法功能:处理动态在线最值问题
3.并查集
算法功能:判断两个集合直接的关系、集合合并
例题1:一共有 n 个数,编号是 1∼n,最开始每个数各自在一个集合中。现在要进行 m 个操作,操作共有两种:
M a b,将编号为 a 和 b 的两个数所在的集合合并,如果两个数已经在同一个集合中,则忽略这个操作;
Q a b,询问编号为 a 和 b 的两个数是否在同一个集合中;
字符串
1.Trie(字典树)
算法功能:判断一个字符串在模式串中出现的次数
例题1:维护一个字符串集合,支持两种操作:
I x 向集合中插入一个字符串 x;
Q x 询问一个字符串在集合中出现了多少次。
2.KMP
算法功能:线性复杂度求匹配串在模式串出现的位置
例题1:给定一个模式串 S,以及一个模板串 P,所有字符串中只包含大小写英文字母以及阿拉伯数字。模板串 P 在模式串 S 中多次作为子串出现。求出模板串 P 在模式串 S 中所有出现的位置的起始下标。
3.Boyer-Moore算法
算法功能:线性复杂度求匹配串在模式串出现的位置
与KMP功能相同但是速度是其3-5倍
4.Z函数(扩展KMP)
算法功能:求对于原串S1的每一个后缀子串与模式串S2的最长公共前缀
例题1:Passwrod
例题2:给定一个长度为n 的字符串s,找到其最短的整周期,即寻找一个最短的字符串t ,使得 可以被若干个t 拼接而成的字符串表示。
5.AC自动机
算法功能:多匹配串在模式串出现的次数
例题1:给定 n 个模式串 s i 和一个文本串 t,求有多少个不同的模式串在文本串里出现过。
两个模式串不同当且仅当他们编号不同。
6.后缀数组(SA)
算法功能:主要有两个数组,通过sa[i]表示将所有后缀排序后第 小的后缀的编号,rank[i]表示后缀 i的排名,也就是通过这两个数组你可以知道排名第几的后缀字符串是谁,并且可以知道一个字符串排名第几。
算法应用:
1.寻找最小的循环移动位置
2.从字符串首尾取字符最小化字典序
3.求LCP(最长公共前缀)
7.后缀自动机(SAM)
算法功能:
1.在另一个字符串中搜索一个字符串的所有出现位置。
2.计算给定的字符串中有多少个不同的子串。
3.字典序第 k 大子串
4.最小循环移位
5.最短的没有出现的字符串
6.两个字符串的最长公共子串
7.所有不同子串的总长度
8.子串出现次数
9.多个字符串间的最长公共子串
例题1:SAM模板
8.后缀平衡树
其中序遍历即为后缀数组。
优点:
1.后缀平衡树的复杂度不依赖于字符集的大小
2.后缀平衡树支持在字符串开头删除一个字符
3.后缀平衡树可持久化
例题1:后缀平衡树模板
例题2:后缀排序
9.广义后缀自动机
后缀自动机 (suffix automaton, SAM) 是用于处理单个字符串的子串问题的强力工具。
而广义后缀自动机 (General Suffix Automaton) 则是将后缀自动机整合到字典树中来解决对于多个字符串的子串问题
例题1:本质不同字串
10.Manacher(马拉车)
算法功能:线性复杂度找到字符串中所有的回文子串
例题1:给定一个长度为 n 的由小写字母构成的字符串,求它的最长回文子串的长度是多少。
11.回文树
算法功能:回文树 (EER Tree,Palindromic Tree,也被称为回文自动机)是一种可以存储一个串中所有回文子串的高效数据结构,使用回文树可以简单高效地解决一系列涉及回文串的问题。
例题1:回文串
12.序列自动机
算法功能:
下面,给两个小写字母串A ,B请你计算:
A 的一个最短的子串,它不是B 的子串
A 的一个最短的子串,它不是 B 的子序列
A的一个最短的子序列,它不是 B的子串
A的一个最短的子序列,它不是 B的子序列
例题1:最短不公共子串
13.最小表示法
字符串 S的最小表示为与 S循环同构的所有字符串中字典序最小的字符串
14.Lyndon 分解
将字符串s唯一分解为若干个简单串
简单串是字典序小于所有后缀串的字符串
15.Main-Lorentz 算法
问题描述:
给定一个长度为n 的字符串 s。
我们将一个字符串连续写两遍所产生的新字符串称为 重串 (tandem repetition)。下文中,为了表述精准,我们将被重复的这个字符串称为原串。换言之,一个重串等价于一对下标 (i,j),其使得s[i…j] 是两个相同字符串拼接而成的。
你的目标是找出给定的字符串 s中所有的重串。
图论
DFS
算法功能:图的遍历、树的遍历、暴力枚举、迷宫问题
例题1:给定一个整数 n,将数字 1∼n 排成一排,将会有很多种排列方法。现在,请你按照字典序将所有的排列方法输出。
例题2:(八皇后)n−皇后问题是指将 n 个皇后放在 n×n 的国际象棋棋盘上,使得皇后不能相互攻击到,即任意两个皇后都不能处于同一行、同一列或同一斜线上。
BFS
算法功能: 最小步数、迷宫问题、图的遍历、树的遍历
例题1:给定一个 n×m 的二维整数数组,用来表示一个迷宫,数组中只包含 0 或 1,其中 0 表示可以走的路,1 表示不可通过的墙壁。最初,有一个人位于左上角 (1,1) 处,已知该人每次可以向上、下、左、右任意一个方向移动一个位置。请问,该人从左上角移动至右下角 (n,m) 处,至少需要移动多少次。数据保证 (1,1) 处和 (n,m) 处的数字为 0,且一定至少存在一条通路。
最短路径
算法功能:求某点-某点的最短路径
1.Floyd(多源最短路) O(N3)
2.Dijkstra 堆优化(稀疏图)O(mlogn)、朴素(稠密图)O(n2)
以上 不可处理负权
3.SPFA O(m)-O(n*m) 可处理负权
例题1:给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环, 边权可能为负数。请你求出 1 号点到 n 号点的最短距离,如果无法从 1 号点走到 n 号点,则输出 impossible。数据保证不存在负权回路。
最小生成树
算法功能:求联通图中最小生成树
1.Prim
2.Kruskal
搜索
深度优先搜索(DFS Depth first search)
过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次.常常指利用递归函数方便地实现暴力枚举的算法
例题1:把正整数 n分解为 3 个不同的正整数,如6=1+2+3 ,排在后面的数必须大于等于前面的数,输出所有方案。
例题2:按照字典序输出自然数 1 到 nn所有不重复的排列,即 nn 的全排列,要求所产生的任一数字序列中不允许出现重复的数字。
广度优先搜索(BFS Breadth First Search)
其算法核心就是在树上做层次遍历
广泛应用于最短路径、最小步数问题,并用于AC自动机、拓扑排序等多类算法中。
例题1:走迷宫
记忆化搜索
用数组来记录已经搜索过的答案,其特点是不依赖任何 外部变量,答案以返回值的形式存在,而不能以参数的形式存在,对于相同一组参数,dfs 返回值总是相同的。所以遇到时直接返回能够大大的优化时间复杂度,其本质是动态规划。
剪枝搜索
暴力搜索时将一些不可能的作为答案的分支直接舍去
常见剪枝思路有:
最优性剪枝:判断一下当前解是否已经差于已有解。
极端法:考虑极端情况,如果最极端(最理想)的情况都无法满足,那么肯定实际情况搜出来的结果不会更优了。
调整法:通过对子树的比较剪掉重复子树和明显不是最有“前途”的子树。
数学方法:比如在图论中借助连通分量,数论中借助模方程的分析,借助不等式的放缩来估计下界等等。
Alpha——Beta剪枝
双向搜索
双向同时搜索的基本思路是从状态图上的起点和终点同时开始进行 广搜 或 深搜。如果发现搜索的两端相遇了,那么可以认为是获得了可行解。可以将复杂度指数型折半O(ab)->O(ab/2)
例题1:字符串变换
Meet in the middle
与双向搜索类似,其思想是搜索分块并合并答案
例题1:Light
启发式搜索(heuristic search)
在普通搜索算法的基础上引入了启发式函数,该函数的作用是基于已有的信息对搜索的每一个分支选择都做估价,进而选择分支。简单来说,启发式搜索就是对取和不取都做分析,从中选取更优解或删去无效解。
A*
属于启发式搜索对BFS的优化,其启发函数构造方式是通过起点的距离函数与终点的距离函数二者之和,是一种在图形平面上,对于有多个节点的路径求出最低通过成本的算法,主要通过三角不等式来优化剪枝。
例题1:第K短路
例题2:八数码
迭代加深
深度优先搜索的优化,其核心思想是每次限制最大深度,然后依次增加搜索深度,直至找到答案,可以视为BFS的一种空间优化。
例题1:加成序列
IDA*
也叫做迭代加深的A算法,将A算法中的BFS改为了DFS
例题1:排书
数学
1.高精度
题面关键词:数据范围很大
算法功能:处理无法用整型解决的大范围数据的加减乘除
2.质数筛(质数判断)
题面关键词:质数
算法功能:快速筛选出质数
1.埃氏筛 时间复杂度:O(NloglogN)
2.欧拉筛(线性筛) 时间复杂度 O(N)
3.米勒罗宾素数检测法 较大数的较快素性判断
3.三角形面积海伦公式
double S(double a,double b,double c)
{
double p=(a+b+c)/2;
double S=sqrt(p*(p-a)*(p-b)*(p-c));
}