SPOJ - REPEATS Repeats (后缀数组)】的更多相关文章

[题目链接] http://www.spoj.com/problems/REPEATS/en/ [题目大意] 求重复次数最多的连续重复子串的长度. [题解] 考虑错位匹配,设重复部分长度为l,记s[i]和s[i+l]前缀匹配得到的最长长度为r,枚举所有的l和i,得到r,那么答案就是r/l+1的最大值.计算任意后缀的最长公共前缀可以利用后缀数组+ST表来解决,两个后缀的最长公共前缀就是他们名次之间的h数组的最小值. 显然,枚举i和l的复杂度达到了O(n2),是没有办法完成统计的,我们发现每个区段只…
字体颜色如何 字体颜色 SPOJ - REPEATS 题意 给出一个字符串,求重复次数最多的连续重复子串. 题解 引自论文-后缀数组--处理字符串的有力工具. 解释参考博客 "S肯定包括了字符r[0], r[L], r[L * 2],r[L * 3], --中的某相邻的两个" 由于当前S是有两个长度为L的连续重复子串拼接而成的,那意味着S[i]和S[i+L] ( 0≤i<L )必定是一样的字符 而这两个字符位置相差L 而字符r[0],r[L],r[L * 2],r[L * 3],…
题意: 给定一个串\(s\),\(s\)必有一个最大循环节的连续子串\(ss\),问最大循环次数是多少 思路: 我们可以知道,如果一个长度为\(L\)的子串连续出现了两次及以上,那么必然会存在\(s[0].s[L].s[2L] \cdots s[L * k]\)中至少有两个连续的位置是相同的,然后看字母\(s[L * i]和s[L * (i + 1)]\)往前往后最多能匹配多远,记住总长度\(len\),那么最大循环次数为\((len / L) + 1\). 参考: SPOJ 687. Repe…
REPEATS - Repeats no tags  A string s is called an (k,l)-repeat if s is obtained by concatenating k>=1 times some seed string t with length l>=1. For example, the string s = abaabaabaaba is a (4,3)-repeat with t = aba as its seed string. That is, th…
Lexicographical Substrings Search \[ Time Limit: 149 ms \quad Memory Limit: 1572864 kB \] 题意 给出一个字符串,求出这个字符串上字典序第 \(k\) 小的子串. 思路 对于给出的字符串,求出后缀数组,根据后缀数组的 \(height\) 数组,我们可以很容易得到一个字符的总子串个数是 \(\sum_{i=1}^{n} (n-sa[i]+1-height[i])\),利用这个式子,就可以求出第 \(k\) 小…
给定一个字符串,求不相同的子串的个数. 假如给字符串“ABA";排列的子串可能: A B A AB  BA ABA 共3*(3+1)/2=6种; 后缀数组表示时: A ABA BA 对于A和AB height[i]=1; 表明一个长度公共,所以ABA中多出现了A这个子串,所以6-1=5: 对于ABA BA height[i]=0,所以不需要减去. 最后答案为5: #include<iostream> #include<stdio.h> #include<string…
一个初步的想法是我们枚举重复子串的长度\(L\).然后跑一遍SA.然后我们枚举一个点\(i\),令他的对应点为\(i+L\),然后求出这两个点的LCP和LCS的长度答案就是这个点的答案就是\((len(LCP)+len(LCS)+L-1)/L\).这个可以用跟\(EXKMP\)的类似的方法证明. 但是这样会T. 那么如何优化?我们在\(1,1+L,1+L*2...\)这些位置设置关键点(这个方法比较常见).然后枚举每一个点改成每一个关键点.这样为什么会对?当我们对一个不是关键点的点求\(LCP\…
题目链接 POJ2774 SPOJ1811 LCS - Longest Common Substring 比后缀自动机慢好多(废话→_→). \(Description\) 求两个字符串最长公共子串 \(Solution\) 任何一个子串一定是某个后缀的前缀 可以将两个字符串拼在一起,中间用一个从未出现过的字符隔开,这样ht[]的最大值就是答案? 不一定,最大的ht[]可能是由同一个字符串得到的,判一下属于哪个字符串即可 //3772K 516MS //SPOJ:26M 0.11s(N=5e5)…
传送门:DISUBSTR 题意:给定一个字符串,求不相同的子串. 分析:对于每个sa[i]贡献n-a[i]个后缀,然后减去a[i]与a[i-1]的公共前缀height[i],则每个a[i]贡献n-sa[i]-height[i]个不同子串. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using name…
思路: 论文题*n Σn-i-ht[i]+1 就是结果 O(n)搞定~ //By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 55555 int cases,n,cntA[N],cntB[N],A[N],B[N],rk[N],sa[N],tsa[N],ht[N]; char s[N]; void SA(){ memse…