入門部落格
p3809 【模板】字尾排序
p4051 [jsoi2007]字元加密
將字串s複製為ss,做字尾陣列。
p2870 [usaco07dec]best cow line g
題意
給出乙個字串,每次可以從字串的首位取出乙個字元,放到佇列的尾部,求可以得到的最小的字典序是多少?
思路
pre[i]
表示以i開頭的字首(即把以i結尾的字首倒過來)
suf[i]
表示以i開頭的字尾
當str[l]!=str[r]
的時候取小的。
相等的時候直接比較pre[r]
和suf[l]
的排名
題解musical theme
題意
給出n個1-88組成的音符,讓找出乙個最長的連續子串行,滿足以下條件:
長度大於5
不重疊的出現兩次(這裡的出現可以經過變調,即這個序列的每個數字全都加上乙個整數x)
思路
我們處理一下這個所謂的「變調」:令a[i]=a[i+1]-a[i]
,這樣就轉化成了找最長的出現至少兩次的相隔至少為1的不重疊子串。(這時長度變為n-1)
先二分答案,把題目變成判定性問題:判斷是否存在兩個長度為k的子串是相同的,且不重疊。解決這個問題的關鍵還是利用height陣列。把排序後的字尾分成若干組,其中每組的字尾之間的height值都不小於k。例如,字串為「aabaaaab」,當k=2時,字尾分成了4組,如圖所示。題解容易看出,有希望成為最長公共字首不小於k的兩個字尾一定在同一組。然後對於每組字尾,只須判斷每個字尾的sa值的最大值和最小值之差是否不小於k。如果有一組滿足,則說明存在,否則不存在。整個做法的時間複雜度為o(nlogn)。本文中利用height值對字尾進行分組的方法很常用,請讀者認真體會
milk patterns
題意
給出n個數字,以及乙個k,求至少出現k次的最長子序列的長度
思路
和poj 1743思路差不多,二分長度,把字尾分成若干組,每組任意字尾公共字首都》=當前二分的長度。統計是否有某個組字尾數量》=k,如果有當前長度就可以。
題解long long message
題意
給出兩個字串,讓找出最長的公共子串
思路
把兩個字串合起來,做最長不重疊子串即可。
題解題意
給出乙個字串s,求s最多由幾個相同的字串重複而成(最小迴圈節的重複次數)
思路
判斷k是不是迴圈節,只需判斷lcp(1,k+1)是否是n−k。
具體原理如下圖:
對於lcp(1,k+1)
我們可以o(n)的預處理出所有height[i]到height[rank[1]]的最小值。
另外倍增會超時,要用到dc3演算法,此演算法複雜度為o(n)。
題解spoj - repeats
題意
給出乙個字串,求重複次數最多的連續重複子串。
題解
poj - 3693
題意
spoj - repeats 的高階版,在這題的基礎上輸出字典序最小的重複字串。
思路
跟上題一樣,先求出最長的重複次數,在求的過程中順便紀錄最多次數可能的長度。
因為sa陣列是按照字典序排好的,所以我們順序遍歷sa陣列,列舉所有長度,判斷當前連續長度是否等於最長的,找到第乙個符合的輸出。
題解common substrings
題意
給出兩個字串,求他倆長度》=k的公共子串的數量。
題解
new distinct substrings
題意
給出t個字串,問每個字串有多少個不同的子串。
思路
按照字尾排序,遍歷字尾,每次新增的字首就是除了 與上乙個字尾的所有公共字首 之外的字首。
答案就是用總數-重複的 即\(\frac-\sum_^height[i]\)
題解
練習 字尾陣列題目
題意 給乙個字串,求最長的出現至少k次的子串,子串可以重疊。難度 和模型一樣,直接上。code include include include using namespace std const int max n 20005 int n,k,a max n void init int ws 100...
Codeforces 字尾陣列 題目彙總
模板1 字串從0開始讀入 const int n 2e5 10,inf 0x3f3f3f3f int sa n int rk n int tmp n int lcp n char s n t n int n,k bool cmp int i,int j void get height 123d.st...
字尾陣列題目選講
複習題 luogu題單 1.noi2015 品酒大會 題意 forall i 0,n 求有多少對字尾滿足 lcp ge i 以及滿足條件的兩個字尾的權值乘積的最大值。我們統計出對於 1.n 中的每個 i 統計一下有多少個 lcp i 再做個字尾和。因為 lcp i,j min st times ed...