1、字尾陣列
可參考 ,最簡單的理解,字尾陣列是「排第幾的是誰?」,名次陣列是「你排第幾?」。關於字尾陣列生成,參考專門演算法。不列。常見筆試題
(1) 可重疊最長重複子串。給定乙個字串,求最長重複子串,這兩個子串可以重疊。
『解析』只需要求height 陣列裡的最大值即可。
(2) 不可重疊最長重複子串。給定乙個字串,求最長重複子串,這兩個子串不能重疊。
『解析』先二分答案,把題目變成判定性問題:判斷是否存在兩個長度為k 的子串是相同的,且不重疊。解決這個問題的關鍵還是利用height 陣列。把排序後的字尾分成若干組,其中每組的字尾之間的height 值都不小於k。例如,字串為「aabaaaab」,當k=2 時,字尾分成了4 組:
(3) 可重疊的k 次最長重複子串。給定乙個字串,求至少出現k 次的最長重複子串,這k 個子串可以重疊。
『解析』 先二分答案,然後將字尾分成若干組。不同的是,這裡要判斷的是有沒有乙個組的字尾個數不小於k。如果有,那麼存在k 個相同的子串滿足條件,否則不存在。這個做法的時間複雜度為o(nlogn)。
(4) 最長回文子串。給定乙個字串,求最長回文子串。
『解析』 將整個字串反過來寫在原字串後面,中間用乙個特殊的字元隔開。這樣就把問題變為了求這個新的字串的某兩個字尾的最長公共字首。
(5) 連續重複子串。給定乙個字串l,已知這個字串是由某個字串s 重複r 次而得到的,求r 的最大值。
『解析』窮舉字串s 的長度k,然後判斷是否滿足。判斷的時候,先看字串l 的長度能否被k 整除,再看suffix(1)和suffix(k+1)的最長公共字首是否等於n-k。在詢問最長公共字首的時候,suffix(1)是固定的,所以rmq問題沒有必要做所有的預處理, 只需求出height 陣列中的每乙個數到height[rank[1]]之間的最小值即可。整個做法的時間複雜度為o(n)。
(6) 重複次數最多的連續重複子串。給定乙個字串,求重複次數最多的連續重複子串。
『解析』先窮舉長度l,然後求長度為l 的子串最多能連續出現幾次。首先連續出現1 次是肯定可以的,所以這裡只考慮至少2 次的情況。假設在原字串中連續出現2 次,記這個子字串為s,那麼s 肯定包括了字元r[0], r[l], r[l*2],r[l*3], ……中的某相鄰的兩個。所以只須看字元r[l*i]和r[l*(i+1)]往前和往後各能匹配到多遠,記這個總長度為k,那麼這裡連續出現了k/l+1 次。最後看最大值是多少。
窮舉長度l 的時間是n,每次計算的時間是n/l。所以整個做法的時間複雜度是o(n/1+n/2+n/3+……+n/n)=o(nlogn)。
(7) 最長公共子串。給定兩個字串a 和b,求最長公共子串。
『解析』先將第二個字串寫在第乙個字串後面,中間用乙個沒有出現過的字元隔開,再求這個新的字串的字尾陣列。當suffix(sa[i-1]) 和suffix(sa[i])不是同乙個字串中的兩個字尾時,max才是滿足條件
(8) 長度不小於k 的公共子串的個數。給定兩個字串a 和b,求長度不小於k 的公共子串的個數(可以相同)。
『解析』基本思路是計算a 的所有字尾和b 的所有字尾之間的最長公共字首的長度,把最長公共字首長度不小於k 的部分全部加起來。先將兩個字串連起來,中間用乙個沒有出現過的字元隔開。按height 值分組後,接下來的工作便是快速的統計每組中字尾之間的最長公共字首之和。掃瞄一遍,每遇到乙個b 的字尾就統計與前面的a 的字尾能產生多少個長度不小於k 的公共子串,這裡a 的字尾需要用乙個單調的棧來高效的維護。然後對a 也這樣做一次。
2、伴隨陣列
其實搜了下伴隨陣列,參考其他都沒這個說法,姑且認為是這麼叫吧,就是定義乙個輔助儲存空間,跟計數排序的陣列挺像,在不少地方,求親合數,求完數,求素數都可以用到
比如,素數的篩選法實現
#include #include using namespace std;
const int max = 100000 ;
bool prime[max];
void searchprime()
} }}int main()
;int main()
for (i=2 ; i < n>>1; i++)
}for (i = 200; i < n; i++)
}return 0;
}
完數的實現
#include #include using namespace std;
const int n = 50000;
int sum[n] = ;
int main()
for (i=2 ; i < n>>1; i++)
}for (i = 1; i < n; i++)
}return 0;
}
三段**都非常相似,定義乙個輔助陣列,2個是儲存因子的和,1個是儲存是否是素數的標記,純粹像計數排序了
沒了,先就這樣吧
字首陣列字尾陣列
連續兩天的周賽,雙周賽都用到了,記錄一下。給你乙個字串 s 它僅包含字元 a 和 b 你可以刪除 s 中任意數目的字元,使得 s 平衡 我們稱 s 平衡的 當不存在下標對 i,j 滿足 i j 且 s i b 同時 s j a 請你返回使 s 平衡 的 最少 刪除次數。輸入 s aababbab 輸...
字尾陣列入門,字尾陣列模板整理
我自己懶得寫,就是想寫個部落格儲存下大佬的部落格位址 點這模板題 大佬的模板 include include include include include include include include include include include define inf 0x3f3f3f3f d...
字尾樹 字尾陣列
在字串處理當中,字尾樹和字尾陣列都是非常有力的工具,其中字尾樹大家了解得比較多,關於字尾陣列則很少見於國內的資料。其實字尾陣列是字尾樹的乙個非 常精巧的替代品,它比字尾樹容易程式設計實現,能夠實現字尾樹的很多功能而時間複雜度也不太遜色,並且,它比字尾樹所占用的空間小很多。可以說,在資訊學競賽 中字尾...