Kuangbin后缀数组专题:
- C - Distinct Substrings SPOJ - DISUBSTR
- 本质不同子串的个数:
- 后缀数组:ans= ( ∑ i = 2 n n − s a [ i ] + 1 − h e i g h t [ i ] ) + n − s a [ 1 ] + 1 (\sum_{i=2}^{n}n-sa[i]+1-height[i])+n-sa[1]+1 (∑i=2nn−sa[i]+1−height[i])+n−sa[1]+1
- 后缀自动机:ans= ∑ n s [ i ] . l e n − n s [ n s [ i ] . f a ] . l e n \sum ns[i].len-ns[ns[i].fa].len ∑ns[i].len−ns[ns[i].fa].len
- 字符串hash:?没想,之后补
- D - 与C相同,不赘述
- E - Power Strings POJ - 2406
- 串的最小循环周期
- 最简便方法:kmp
- 后缀自动机:?没想,之后补
- 后缀数组: 遍历循环节长度len:O(n/len)*log(len)用LCP check
- 字符串hash:遍历循环节长度len:O[n/len]的check
- F - Repeats SPOJ - REPEATS
- 循环次数最多的子串的次数
- 后缀自动机:?没想,之后补
- 后缀数组:遍历循环节长度len,先看所有从ilen开始的子串,得出这类串的 a n s = 1 + l c p ( i ∗ l e n , i ∗ l e n + l e n ) ans=1+lcp(i*len,i*len+len) ans=1+lcp(i∗len,i∗len+len),再对于不以ilen开始的子串, n e e d = l e n − l c p ( i ∗ l e n , i ∗ l e n + l e n ) , 求 出 a n s = l c p ( i ∗ l e n − n e e d , i ∗ l e n − n e e d + l e n ) need=len-lcp(i*len,i*len+len),求出ans=lcp(i*len-need,i*len-need+len) need=len−lcp(i∗len,i∗len+len),求出ans=lcp(i∗len−need,i∗len−need+len),上述两种ans就组成了len对应的答案,最后求个max就可以了
- 字符串hash:?没想,之后补
- G - Maximum repetition substring POJ - 3693
- 循环次数最多的子串,求其中字典序最小的子串
- 后缀自动机:?没想,之后补
- 后缀数组:用上述方法求出ans,顺便要求出ans对应的所有的可能的len,然后…暴力check,按字典序遍历后缀,每个后缀暴力check每一个可能的len
- 字符串hash:?没想,之后补
- H - Long Long Message POJ - 2774
- LCS 最长公共子串
- 后缀自动机:拿进去跑就完事了
- 后缀数组:把A串和B串拼接起来,i,j是拼接之后的串的下标,i的范围在A内,j的范围在B内,ans=max(lcp(i,j)),直接跑是n^2的,dp就完了
- 字符串hash:?没想,之后补
- I - Common Substrings POJ - 3415
- 长度大于K的子串的个数
- 后缀自动机:
- 后缀数组:求 ∑ i < = n ∑ j > n max ( 0 , min h e i g h t [ i : j ] ) \sum_{i<=n}\sum_{j>n}\max(0,\min{height[i:j]}) ∑i<=n∑j>nmax(0,minheight[i:j])
- 字符串hash: