題目分析:首先觀察到集集合 A 中那個套娃的表示,外層的范圍是 [ x1 , y1 ] ,內(nèi)層是 [ x2 , y2 ] ,而內(nèi)層的定義域?qū)嶋H上是包含在外層的定義域內(nèi)的,這樣外層的函數(shù) f 其實是不起作用的,因為內(nèi)層的函數(shù) f 已經(jīng)按照規(guī)則將區(qū)間集合 A 中 [ x1 , y1 ] 內(nèi)的每個元素按照規(guī)則轉(zhuǎn)換完畢了,再進行一次相同的轉(zhuǎn)換,則就變的可有可無了,換句話說,每一個 f( S , x1 , y1 ) 實質(zhì)上表示為字符串 s 的每個子串經(jīng)過 f 函數(shù)轉(zhuǎn)換后的字符串,這樣題意就變成了求所有子串經(jīng)過 f 函數(shù)的轉(zhuǎn)換后,有多少個本質(zhì)不同的字符串
上面轉(zhuǎn)換后的題意還不夠直接,通過觀察可以發(fā)現(xiàn),假設(shè)字符串 s 在經(jīng)過 f 函數(shù)的轉(zhuǎn)換后,得到新的字符串記為 ss ,不難看出字符串 s 的一個前綴在經(jīng)過 f 函數(shù)的轉(zhuǎn)換后,得到的仍然是 ss 的前綴
參考后綴與子串的關(guān)系,可以將所有的子串表示為任意一個后綴的前綴,同樣題意轉(zhuǎn)換為了所有經(jīng)過 f 函數(shù)轉(zhuǎn)換后的后綴中,有多少個本質(zhì)不同的子串
這樣題意就轉(zhuǎn)換為了求 f( S , i , n ) ,i ∈ [ 1 , n ] ,求 n 個串中本質(zhì)不同的子串,這個可以借助廣義后綴自動機來完成,但是如果暴力為 n 個串建立 sam 的話,時空復(fù)雜度都會爆掉,再根據(jù) f 函數(shù)的性質(zhì)來考慮,可以發(fā)現(xiàn),因為字符集的大小為 10,所以任意一個位置的字符,至多會被更新 9 次,最極端的情況下,假設(shè)字符串為 dcbaaa...aaa,后綴的長度從小到大可以表示為:
a
aa
aaa
......
aaa...aaa
bbbb...bbb
ccccc...ccc
ddddd...ddd
這是最極端的情況,這樣整體建立廣義 sam 的時空復(fù)雜度也不會超過 10N
在建立廣義 sam 時,可以借助序列自動機來實現(xiàn),普通的序列自動機 nx[ i ][ j ] 記錄的是位置 i 后(包括)首次出現(xiàn)字母 j 的位置,在本題中需要轉(zhuǎn)換為:nx[ i ][ j ] 表示為記錄位置 i 后(包括)首次大于等于字母 j 的位置,這樣對于第 i 個位置的字母 j 來說,只需要暴力更新一下 [ i , nx[ i ][ j ] - 1 ] 就好了,nx[ i ][ j ] 往后的位置都可以直接從前面維護的 trie 樹中拉下來繼續(xù)用