字符串专题 1
暑假二南集训 day1
A - GT考试 洛谷 - P3193
[HNOI2008] GT考试
题目描述
阿申准备报名参加 GT 考试,准考证号为 \(N\) 位数\(X_1,X_2…X_n\ (0\le X_i\le 9)\),他不希望准考证号上出现不吉利的数字。
他的不吉利数字\(A_1,A_2,\cdots, A_m\ (0\le A_i\le 9)\) 有 \(M\) 位,不出现是指 \(X_1,X_2\cdots X_n\) 中没有恰好一段等于 \(A_1,A_2,\cdots ,A_m\),\(A_1\) 和 \(X_1\) 可以为 \(0\)。
输入格式
第一行输入 \(N,M,K\) 接下来一行输入 \(M\) 位的数。
输出格式
阿申想知道不出现不吉利数字的号码有多少种,输出模 \(K\) 取余的结果。
样例 #1
样例输入 #1
4 3 100
111
样例输出 #1
81
提示
数据范围及约定
对于全部数据,\(N\leq10^9\),\(M\leq 20\),\(K\leq1000\)。
f[i][j]表示长串匹配到第i位,短串最多可以匹配到第j位的方案数
再使用kmp,失去匹配就跳next。
F - 双倍回文 洛谷 - P4287
[SHOI2011] 双倍回文
题目描述
记字符串 \(w\) 的倒置为 \(w^{\mathsf R}\)。例如\(\tt (abcd)^{\mathsf R}=dcba\),\(\tt (abba)^{\mathsf R}=abba\)。
对字符串 \(x\),如果 \(x\) 满足 \(x^{\mathsf R}=x\),则称之为回文。例如 \(\tt abba\) 是一个回文,而 \(\tt abed\) 不是。
如果 \(x\) 能够写成 \(ww^{\mathsf R} ww^{\mathsf R}\) 形式,则称它是一个“双倍回文”。换句话说,若要 \(x\) 是双倍回文,它的长度必须是 \(4\) 的倍数,而且 \(x\),\(x\) 的前半部分,\(x\) 的后半部分都要是回文。例如 \(\tt abbaabba\) 是一个双倍回文,而 \(\tt abaaba\) 不是,因为它的长度不是 \(4\) 的倍数。
- \(x\) 的子串是指在 \(x\) 中连续的一段字符所组成的字符串。例如 \(\tt be\) 是 \(\tt abed\) 的子串,而 \(\tt ac\) 不是。
- \(x\) 的回文子串,就是指满足回文性质的 \(x\) 的子串。
- \(x\) 的双倍回文子串,就是指满足双倍回文性质的 \(x\) 的子串。
你的任务是,对于给定的字符串,计算它的最长双倍回文子串的长度。
输入格式
输入分为两行。
第一行为一个整数,表示字符串的长度。
第二行有个连续的小写的英文字符,表示字符串的内容。
输出格式
输出文件只有一行即输入数据中字符串的最长双倍回文子串的长度,如果双倍回文子串不存在,则输出 \(0\)。
样例 #1
样例输入 #1
16
ggabaabaabaaball
样例输出 #1
12
提示
数据范围及约定
对于全部数据,\(1\le N \le 500000\)。
可以使用PAM解决,但是显然麻烦了。
因为双倍回文本身也是回文,所以用manacher。
在更新p数组的时候,判断对称中心左半段字串是否为回文,如果是再更新,这样就可以轻松解决。
H - Longest Common Substring https://www.luogu.com.cn/problem/SP1811
LCS - Longest Common Substring
题面翻译
输入两个字符串,输出它们的最长公共子串长度,若不存在公共子串则输出 \(0\)。
其中字符串长度不超过 \(2.5\times 10^5\)。
题目描述
A string is finite sequence of characters over a non-empty finite set Σ.
In this problem, Σ is the set of lowercase letters.
Substring, also called factor, is a consecutive sequence of characters occurrences at least once in a string.
Now your task is simple, for two given strings, find the length of the longest common substring of them.
Here common substring means a substring of two or more strings.
输入格式
The input contains exactly two lines, each line consists of no more than 250000 lowercase letters, representing a string.
输出格式
The length of the longest common substring. If such string doesn't exist, print "0" instead.
样例 #1
样例输入 #1
alsdfkjfjkdsal
fdjskalajfkdsla
样例输出 #1
3
使用SAM。
对于第一个字符串建一个SAM。
第二个字符串再SAM上匹配。
1.p有si的转移,直接跳下去,len++
2.p没有转移,在parent树上往上跳,直到有这个转移为止,并len=len(p)+1,再跳下去
3.跳到头还是没有转移,令p=1,len=0重新开始