【算法介绍】KMP算法
算法简介:巡护深林KMP 算法,虽然我们已经在 【算法介绍】字符串算法 | 祝馀宫 中提及,但是现在有了更深的理解,我们这篇文章单独讲 KMP 算法以及其原理。为了凑字数,我们再讲一遍废话。 KMP 算法,全称 $Knuth-Morris-Pratt$ 算法,通过一种特殊的性质匹配两个字符串,从而达到减少匹配次数的算法。
算法演示:漫行山薮变量定义:夏堇芳菲我们对于接下来的一些内容做出如下定义:
名称
定义
子串
不用多说了罢,在字符串中截取任意一段连续的内容,被称为子串下文用 $s[l\dots r]$ 表示字符串 $s$ 的从 $l$ 到 $r$ 的这部分子串。 下文所有关于字符串的计算都是以 1 为开始的下标*
子序列
不要求连续,但是在原字符串中内容顺序相同的字符串。
前缀子串
一个字符串的前缀组成的子串,表示为 $pre(s,i)=s[1\dots i]$ ,即 $s$ 字符串长度为 $i$ 的前缀
后缀子串
一个字符串的后缀组成的子串,表示为 $suf(s, i) = s[n-i+1\dots n]$ ,即 $s$ 字符串长度为 $i$ 的后缀
...
【拾题杂谈】LuoguP4159 [SCOI2009] 迷路
题面:[SCOI2009] 迷路大秦为你打开题目传送门
题目背景windy 在有向图中迷路了。
题目描述该有向图有 $n$ 个节点,节点从 $1$ 至 $n$ 编号,windy 从节点 $1$ 出发,他必须恰好在 $t$ 时刻到达节点 $n$。
现在给出该有向图,你能告诉 windy 总共有多少种不同的路径吗?
答案对 $2009$ 取模。
注意:windy 不能在某个节点逗留,且通过某有向边的时间严格为给定的时间。
输入格式第一行包含两个整数,分别代表 $n$ 和 $t$。
第 $2$ 到第 $(n + 1)$ 行,每行一个长度为 $n$ 的字符串,第 $(i + 1)$ 行的第 $j$ 个字符 $c_{i, j}$ 是一个数字字符,若为 $0$,则代表节点 $i$ 到节点 $j$ 无边,否则代表节点 $i$ 到节点 $j$ 的边的长度为 $c_{i, j}$。
输出格式输出一行一个整数代表答案对 $2009$ 取模的结果。
样例 #1样例输入 #11232 21100
样例输出 #111
样例 #2样例输入 #21234565 3012045071054780512024123 ...
【拾题杂谈】斐波那契类的矩阵快速幂
前置知识:矩阵快速幂出门右转 【算法介绍】矩阵乘法 | 祝馀宫 喵!
例一:斐波那契前缀和直接求斐波那契的例子已经在上面的文章中讲过了。这里直接开始讲斐波那契的前 n 项和怎么算。
求斐波那契的前 $n$ 项和对于 $m$ 取模的结果。
首先,不难给出递推式:
\begin{cases}
f_1 = 1\\
f_2 = 2\\
f_i = f_{i - 1} + f_{i - 2} \quad (i\ge 3)\\
s_1 = 1\\
s_i = s_{i-1} + f_i\qquad (i\ge 2)
\end{cases}这个是最最基础的递推式子,我们不难想到之前说的列方程法。我们就可以写出下面的方程组。
\begin{cases}
f_{i+1} &= &0\times f_i + 1\times f_{i+1} + 0\times s_i \\
f_{i+2} &= &1\times f_i + 1\times f_{i + 1} + 0\times s_i \\
s_{i+1} &= &0\times f_i + 1\times f_{i + 1} + 1\times ...
【算法介绍】矩阵乘法
算法简介:正绢六通首先,说到矩阵乘法。字面意思的来讲,就是矩阵与矩阵之间的乘法,他们之间是否满足正常数字之间的乘法规则,也就是交换律与结合律呢?这部分的内容都将在下面被解释。
算法演示:落染五色矩阵加法:缀锦四分这个比较简单。首先我们了解一下矩阵的定义,对于一个 $n$ 行 $m$ 列的矩阵,我们有如下的表示方式:
\left[\begin{matrix}
a_{1,1} & a_{1,2} & \cdots & a_{1,m} \\
a_{2,1} & a_{2,2} & \cdots & a_{2,m} \\
\vdots & \vdots & \ddots & \vdots \\
a_{n,1} & a_{n,2} & \cdots & a_{n,m}
\end{matrix}\right]这样的矩阵,就是我们接下来的基础。首先讲到乘法,肯定会有人想到加法。但是实际上……矩阵的加法和乘法几乎一点关系都没有……但是提到了我们也顺便讲一下。
矩阵的运算不同于数字,两个矩阵之间是否可以进行运算,对于矩阵的行和列有着严格的规定。比如说加法,所对应的两个矩阵行和列必须一模一样,因为矩阵加 ...
CSP-2024 游寄
上午:CSP-J 2024题目钛简单,没有打到 300 分的原因是 T3 没有算内存,直接把打表用的程序交了上去喜提 MLE -50
下午:CSP-S 2024题目还是好简单,没有打到 220 分的原因是:
T1 先把被吃的赋值成了 0,然后再让吃的把被吃的吃了…… -25 赛后扫了一眼代码就改了出来,最煞笔的是大样例全过了……
T2 把已经平方的速度再次平方…… -60,也是赛后看了一眼代码就发现了问题,最傻逼的是赛时我调这个问题调了一整个比赛…… 导致 T3 的暴力分都没打……
T3 ,T2 的策略规划不周,以及最傻逼的考场发挥,暴力分没打…… -20
这次 S组 比赛总计挂分 105 分,直接把大众分打成了煞笔分,我是纸张
【算法介绍】树上莫队
算法简介:重帘留香树上莫队,就是字面意思上的树上的莫队,但实际上,一般来讲的树上莫队指的都是用欧拉序把一棵树压成数组,然后对其进行普通莫队的操作。
算法演示:天青现虹算法推导:织诗成锦那么首先我们可以随便画一棵树
然后我们首先手动算一算他的欧拉序。应该是 $[1,2,4,5,5,6,6,7,7,4,2,3,3,1]$ 。
那么我们考虑如果我们需要查询一个路径 $5-4-2-1-3$ ,会发生什么事。那么首先把他转化成欧拉序上的一段,也就是 5 的最后一次出现位置,和 3 的第一次出现位置,那么把它所对应的那一段截取下来就应该是:$[5,6,6,7,7,4,2,3$] ,观察,我们发现这个路径上的点,在这段内容中,多了 6 和 7 但是他们出现次数都是偶数,不难想到用异或或者 vis 去重可以得到,其次是 1 号点,1 号点是 LCA 我们应该需要特殊计算。所以说大概的找找规律,可以知道大概的计算方式。接着就是按照这样的规则模拟即可。
最后有一个细节问题,欧拉序的大小是原来的两倍!
例题讲解:孤舟斩蛟这里提供一道非常非常模板的题目:SP10707
就是在上述板子的基础上统计一波颜色即可 ...
【拾题杂谈】CF1166F - Vicky's Delivery Service
题面题面翻译有 $n$ 个点,$m$ 条边的图,每条边有一种颜色。定义一条路(经过的点是 $c_1,c_2,\dots,c_k$)是彩虹路,要求满足 $2$ 个条件:
对于所有 $1 \le i \le k - 1$,$c_i$ 和 $c_{i+1}$ 有边。
对于所有 $1 \le i \le \dfrac{k-1}{2}$,$c_{2i}$ 和 $c_{2i-1}$ 的边的颜色与 $c_{2i}$ 和 $c_{2i+1}$ 的边的颜色相同。
现在有 $q$ 次操作:
x y z:向点 $x$ 和 $y$ 之间建一条颜色为 $z$ 的边。
? x y:询问 $x$ 点和 $y$ 点之间是否有彩虹路。
思路我们首先可以想到 对于点 xx,它连出去的同种颜色连着的点都是可以相互到达的,所以我们可以将它们用并查集合并。我们要快速查询一个点连出去某种颜色的边,这里用了一个 map 。这样我们就处理完了走偶数步的情况,对于走奇数步的情况,最后一步是随便走的,我们可以对每个集合存一个 set,存集合中能一步走到的点,启发式合并即可
代码1234567891011121314151 ...
【拾题杂谈】CF570D - Tree Requests
题面原题链接大秦 为你打开 题目传送门
题目翻译给定一个以 $1$ 为根的 $n$ 个结点的树,每个点上有一个字母(a-z),每个点的深度定义为该节点到 $1$ 号结点路径上的点数。每次询问 $a, b$ 查询以 $a$ 为根的子树内深度为 $b$ 的结点上的字母重新排列之后是否能构成回文串。
思路首先这道题目一眼就是树上启发式合并,我们大力统计每一个点以及他们的子树里面每个深度每种字母有多少就可以了。代码并没有什么细节敲板子即可。
代码123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 ...
【拾题杂谈】CF1709E - XOR tree
题面原题链接大秦 为你打开 题目传送门
题目翻译你有一棵无根树,点数为 $n$,每个点有个点权 $a_u$,定义一条路径 $P(u,v)$ 的权值为经过的所有点的点权的异或和。定义一棵树是合法的,当且仅当树上所有简单路径(只经过每个点一次的路径)的的权值都不为 $0$。
你可以对权值进行修改,可以改成任意正整数,问最少修改多少次才能让这棵树合法。
输出最小修改次数。
$n\leq 2\times 10^5,a_i\leq 2^{30}$
思路我们不难发现,如果一条路径上的元素异或值为 0 我们设 $dep_i$ 表示 $i$ 号点到根所有路径的值。 那么这个路径一定满足条件 $dep_u\ \oplus\ dep_v\ \oplus\ dep_{lca(u,v)} = 0$ 。那么我们就不难想到,处理出这个节点所有儿子的左右子树里的 dep 值。如果 $v$ 的子树之中存在一个值等于 $u$ 的子树中的一个节点的值异或当前这个节点的值,那么一定存在一条路径在这两个子树之中。那么一劳永逸的方式就是把当前这个作为 lca 的节点替换了,统计答案。
代码1234567891011121314 ...
【拾题杂谈】517八段第十三课D
题面题目链接大秦 为你打开 题目传送门
备用题面给定若干未赋值的变量,并给出 $n$ 组操作,每组操作形如:x y p 。当 $p$ 为 $1$ 时,如果第 $x$ 变量和第 $y$ 个变量可以相等,则输出 YES ,并限制他们必须相等;否则输出 NO ,并忽略此次操作。当 $p$ 为 $0$ 时,如果第 $x$ 变量和第 $y$ 个变量可以不相等,则输出 YES ,并限制他们必须不相等;否则输出 NO ,并忽略此次操作。
思路显而易见的相等关系肯定是用并查集存储,而不等关系我们只需要用 vector 存下来有以后大力合并即可。
代码123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103// #pragma GCC optimize(2)// ...