lcp

后缀数组 最详细讲解

邮差的信 提交于 2020-10-05 15:28:51
转载自 后缀数组 学习笔记 后缀数组 最详细(maybe)讲解 后缀数组这个东西真的是神仙操作…… 但是这个比较神仙的东西在网上的讲解一般都仅限于思想而不是代码,而且这个东西开一堆数组,很多初学者写代码的时候很容易发生歧义理解,所以这里给出一个比较详细的讲解。笔者自己也是和后缀数组硬刚了一个上午外加一个中午才理解的板子。 本人版权意识薄弱,如有侵权现象请联系博主邮箱xmzl200201@126.com 参考文献: 百度百科_后缀数组 %%%曲神学长的blog%%% 以下是不认识的dalao们: wsy的cnblog soda的cnblog I'MJACKY的cnblog 董雨的cnblog 特别感谢以下的两位dalao,写的特别好,打call J.K.的cnblog J_Sure的csdn 什么是后缀数组 我们先看几条定义: 子串 在字符串s中,取任意i<=j,那么在s中截取从i到j的这一段就叫做s的一个子串 后缀 后缀就是从字符串的某个位置i到字符串末尾的子串,我们定义 以s的第i个字符为第一个元素的后缀为suff(i) 后缀数组 把s的每个后缀按照字典序排序, 后缀数组sa[i]就表示 排名为i的后缀 的起始位置的下标 而它的映射数组rk[i]就表示 起始位置的下标为i的后缀 的排名 简单来说,sa表示排名为i的是啥,rk表示第i个的排名是啥 一定要记牢这些数组的意思

水题日记

五迷三道 提交于 2020-08-20 09:20:30
目录 写在前面 2020.8.15 2020.8.15 题 2020.8.15 日记 2020.8.16 2020.8.16 题 2020.8.16 爆零小技巧 2020.8.16 日记 2020.8.17 2020.8.17 题 2020.8.17 爆零小技巧 2020.8.17 日记 2020.8.18 2020.8.18 题 2020.8.18 爆零小技巧 2020.8.18 日记 2020.8.18 2020.8.18 题 2020.8.18 爆零小技巧 2020.8.18 日记 写在最后 写在前面 口嗨区 精神续作。 准备把这个当日记用( 2020.8.15 2020.8.15 题 [JSOI2007]字符加密 代码 SA 板子背诵检查。 断环成链,把字符串复制一遍扔到后面,跑 SA 即可。 SP705 SUBST1 - New Distinct Substrings 代码 SAM 板子背诵检查。 一个字符串唯一对应一个状态, \(ans = \sum\limits_i{\operatorname{len}(i)-\operatorname{len}(\operatorname{link}(i))}\) SP8222 NSUBSTR - Substrings 代码 SAM 板子背诵检查。 按拓扑序求出每个状态出现次数,仅更新 \(F(\operatorname{len}

LCP 模板

自闭症网瘾萝莉.ら 提交于 2020-08-18 12:43:01
LCP Description 给定串 \(S\) . \(m\) 组询问 \((X, Y, L, R)\) : 求 \(S[X,Y]\) 与 \(S[L,R]\) 的最长公共前缀. Input 第一行一个串 \(S\) . 第二行一个数 \(m\) . 接下来 \(m\) 行, 每行 \(4\) 个数 \(X, Y, L, R\) . Output 输出共 \(m\) 行, 第 \(i\) 行为第 \(i\) 个询问的答案. HINT \(1 <= |S| <= 100000\) , 且 \(S\) 由小写字母构成. \(1 <= m <= 100000\) \(1 <= L <= R <= |S|\) \(1 <= X <= Y <= |S|\) LCP标准模板,放一下... Code: #include <cstdio> #include <cstring> #include <algorithm> using std::min; const int N=1e5+10; char s[N]; int tax[N],Rank[N],sa[N],sec[N]; int n,m,q,st[N][20],h[N],height[N],Log[N]; void Rsort() { for(int i=1;i<=m;i++) tax[i]=0; for(int i=1;i<=n;i++)

P2408 不同子串个数(SA-LCP)

冷暖自知 提交于 2020-08-14 03:12:18
P2408 不同子串个数(SA-LCP) 传送门 经典的 S A − L C P SA-LCP S A − L C P 题目。 显然所有子串数目为 n ( n + 1 ) 2 \dfrac{n(n+1)}{2} 2 n ( n + 1 ) ​ 。 因此我们只需知道重复的子串有多少个。 根据 L C P LCP L C P 我们知道利用 L C P LCP L C P 求出的 h e i g h t [ i ] = L C P ( i , i − 1 ) , 即 排 名 第 i 名 和 第 i − 1 名 的 最 长 公 共 前 缀 height[i]=LCP(i,i-1),即排名第i名和第i-1名的最长公共前缀 h e i g h t [ i ] = L C P ( i , i − 1 ) , 即 排 名 第 i 名 和 第 i − 1 名 的 最 长 公 共 前 缀 ,他们的长度即是重复的子串个数,这样求的正确性是因为要找到重复的子串,首先两个子串下标必须不一样,且长度一样,字母完全一样,所以根据排名第 i i i 名和第 i − 1 i-1 i − 1 名是字典序最接近的可以知道 h e i g h t [ i ] height[i] h e i g h t [ i ] 求代表重复子串个数,求和便可得到重复子串总数。 所以 a n s = n ( n + 1 ) 2 − ∑ i

第六章 接入到互联网

假装没事ソ 提交于 2020-08-14 02:51:25
接入到互联网 使用PPP协议建立广域网连接 什么是PPP协议 PPP概述 PPP数据链路层协议可以用于异步串行(拨号)或同步串行(ISDN)介质。它使用LCP(链路控制协议)建立并维护数据链路连接。网络控制协议(NCP)允许在点到点连接上使用多种网络层协议(被动路由协议)。如图所示。 PPP组件 PPP包含4个主要组件: 01 EIA/TIA-232-C、V.24、 V.35 和ISDN串行通信的物理层国际标准。 02 HDLC在串行链路上封装数据报的方法。 03 LCP- 种建立、配置、维护和结束点到点连接的方法。 04 NCP一种建立和配置不同网络层协议的方法。 NCP设计允许同时使用多个网络层协议。例如有些协议是IPCP(Intern et Protocol Control Protocol ,因特网协议控制协议)和IPXCP(Internetwork Packet Exchange Control Protocol,互联网络包交换控制协议)。 链路控制协议( LCP )配置选项 链路控制协议(Link control Protocol,LCP)提供各种PPP封装选项,包括如下内容。 01 Authentication(认证)这个选项告诉链路的呼叫方发送可以确定其用户身份的信息。两种认证方法是PAP和CHAP。 Compression(压缩

后缀三姐妹

点点圈 提交于 2020-08-13 09:24:04
目录 写在前面 一些约定 后缀数组 SA SA 的定义 前置知识 计数排序 基数排序 倍增法构造 优化 代码及解释 再优化 LCP 问题 一些定义 引理:LCP Lemma 引理:LCP Theorem 推论:LCP Corollary 引理 快速求 height 后缀树 暴力构建 虚树 + SA 前置小碎骨 构建方法 套 SA 后缀自动机 Ukkonen 后缀自动机 SAM 前置米斯琪 引入 SAM 的定义 独特概念 结束位置 endpos DAWG 后缀链接 Link parent 树 小结 构造 SAM 复杂度 写在最后 绝对不咕 一篇就够了! 写在前面 会考虑整个与标题相关的二次创作。 什么时候有能力再说 一些约定 \(\mid \sum \mid\) :字符集大小。 \(S[i:j]\) :由字符串 \(S\) 中 \(S_i\sim S_j\) 构成的子串。 \(S_1<S_2\) :字符串 \(S_1\) 的字典序 \(<S_2\) 。 后缀:从某个位置 \(i\) 开始,到串末尾结束的子串,后缀 \(i\) 等价于子串 \(S[i:n]\) 。 后缀数组 SA 网上部分题解直接开讲优化后面目全非的代码。 *这太野蛮了* 这里参考了 OI-wiki 上的讲解。 SA 的定义 字符串 \(S\) 的后缀数组 \(A\) ,被定义为一个数组,内容是其所有后缀

「赛前备战」NOIp2020-提高 图论训练

你说的曾经没有我的故事 提交于 2020-08-13 06:10:47
博主太菜,可能会炸联赛,于是恶补一下 QAQ 题目比较基础,动态更新 Tags 生成树 , 最短路 , 差分约束 , 树的直径与重心 , LCA , 树链剖分 , 拓扑序 , 强连通分量 , 割点 , 桥 , 点双连通分量 , 边双连通分量 , 2-SAT , 二分图 , 正/负环 , 最小环 Content 「Codeforces 888G」Xor-MST 生成树 「AtCoder JSC2019 Qual E」Card Collector 生成树 「Codeforces 888G」Xor-MST update - 2020.8.4 此题需要用到一个叫 Borůvka 的最小生成树算法,大致就是对现在的每一个连通块都找一遍的最短边,最后每个连通块择优,将这些边全部连上。这样复杂度之正确的原因可以参考启发式合并, \(O(|E|\log |V|)\) 。 对于此题,我们以可以用这样的思路来“择优合并”,即选取两个结点 \(u, v\) ,使得 \(a_u \oplus a_v\) 最小,然后合并。现在如何找到这个最小的就是个问题。 对于两个二进制数 \(x = (10001010)_2,y = (10000110)_2\) ,前 \(4\) 位相同,即 \(\text{lcp} = 4\) ,那么异或一次前四位都是 \(0\) 。我们优先考虑二进制下 \(\text{lcp}\)

Leetcode:LCP 13. 寻宝 状态压缩动态规划

℡╲_俬逩灬. 提交于 2020-08-11 23:28:08
题目 我们得到了一副藏宝图,藏宝图显示,在一个迷宫中存在着未被世人发现的宝藏。 迷宫是一个二维矩阵,用一个字符串数组表示。它标识了唯一的入口(用 ‘S’ 表示),和唯一的宝藏地点(用 ‘T’ 表示)。但是,宝藏被一些隐蔽的机关保护了起来。在地图上有若干个机关点(用 ‘M’ 表示),只有所有机关均被触发,才可以拿到宝藏。 要保持机关的触发,需要把一个重石放在上面。迷宫中有若干个石堆(用 ‘O’ 表示),每个石堆都有无限个足够触发机关的重石。但是由于石头太重,我们一次只能搬一个石头到指定地点。 迷宫中同样有一些墙壁(用 ‘#’ 表示),我们不能走入墙壁。剩余的都是可随意通行的点(用 ‘.’ 表示)。石堆、机关、起点和终点(无论是否能拿到宝藏)也是可以通行的。 我们每步可以选择向上/向下/向左/向右移动一格,并且不能移出迷宫。搬起石头和放下石头不算步数。那么,从起点开始,我们最少需要多少步才能最后拿到宝藏呢?如果无法拿到宝藏,返回 -1 。 示例 1 : 输入: [ "S#O" , "M.." , "M.T" ] 输出: 16 解释:最优路线为: S - > O , cost = 4 , 去搬石头 O - > 第二行的M , cost = 3 , M机关触发 第二行的M - > O , cost = 3 , 我们需要继续回去 O 搬石头。 O - > 第三行的M , cost = 4 ,

HDU 6194 string string string 后缀数组+lcp、Two Pointers

北慕城南 提交于 2020-08-09 12:04:03
string string string Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 989 Accepted Submission(s): 285 Problem Description Uncle Mao is a wonderful ACMER. One day he met an easy problem, but Uncle Mao was so lazy that he left the problem to you. I hope you can give him a solution. Given a string s, we define a substring that happens exactly k times as an important string, and you need to find out how many substrings which are important strings. Input The first line contains an integer T ( T ≤ 100 ) implying the number of test cases. For each

LeetCode 410. 分割数组的最大值(极小极大化 二分查找 / DP)

泄露秘密 提交于 2020-08-09 10:41:31
文章目录 1. 题目 2. 解题 2.1 二分查找 2.2 DP 1. 题目 给定一个非负整数数组和一个整数 m,你需要将这个数组分成 m 个非空的连续 子数组。 设计一个算法使得这 m 个子数组 各自和 的 最大值最小 。 注意 : 数组长度 n 满足以下条件 : 1 ≤ n ≤ 1000 1 ≤ m ≤ min ( 50 , n ) 示例 : 输入 : nums = [ 7 , 2 , 5 , 10 , 8 ] m = 2 输出 : 18 解释 : 一共有四种方法将nums分割为 2 个子数组。 其中最好的方式是将其分为 [ 7 , 2 , 5 ] 和 [ 10 , 8 ] , 因为此时这两个子数组各自的和的最大值为 18 ,在所有情况中最小。 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/split-array-largest-sum 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 2. 解题 2.1 二分查找 类似题目: LeetCode 875. 爱吃香蕉的珂珂(二分查找) LeetCode LCP 12. 小张刷题计划(二分查找) LeetCode 1011. 在 D 天内送达包裹的能力(二分查找) LeetCode 1062. 最长重复子串(二分查找) LeetCode 5438. 制作