SAM複習題表

2021-08-17 06:09:31 字數 3454 閱讀 8263

今天重新學了一下sam

那麼一些題目肯定是少不了的

在這裡記錄一下吧,可能沒什麼啟發的題就不寫了

題意:多個串的最長公共子串

題解:對於乙個建立sam,然後對於剩下的所有點在上面跑,對於每乙個點的狀態取最小值。但是這樣是不夠的,你還要跳一次fail來進行更新,這個的話拓撲更新就可以了

題意:求第k大串

題解:直接預處理出每個點往下可以走多少個就可以了

題意:定義乙個字元x,他的識別子串是包含他且僅出現一次的子串,問每個字元的最小識別子串

題解:這題做出來了很開心啊,看來昨天不是白學的。考慮到對於乙個點,僅出現一次就是right集合是1的點。我們對於這些點記錄他的right集合,因為只有乙個元素,這裡我記為pos,然後考慮這個點,他可以表示的串是[p

os[x

]−ma

x[x]

+1,p

os[x

]−mi

n[x]

+1].

..po

s[x]

[ po

s[x]

−max

[x]+

1,po

s[x]

−min

[x]+

1]..

.pos

[x

]可以知道如果左端點在ma

x[x]

+1,p

os[x

]−mi

n[x]

+1] max

[x]+

1,po

s[x]

−min

[x]+

1]

,那麼這個子串的長度就是po

s[x]

−l+1

p os

[x]−

l+

1,當po

s[x]

p os

[x

]取得最小的時候最小

如果是在[p

os[x

]−mi

n[x]

,pos

[x]]

[ po

s[x]

−min

[x],

pos[

x]

]的話,那麼這個子串的長度最小是mi

n[x]

m in

[x

]的,這個的話當覆蓋的子串mi

n[x]

m in

[x

]最小的時候最小

用線段樹維護這兩個東西就可以了

題意:n個串,m個串,問m個串每個在前n個串中的幾個出現過。

題解:這題的話,顯然是乙個廣義字尾自動機啊

然後維護,乙個節點在多少個串裡面出現過有兩個方法

①:對於每加入乙個節點,就標記一下他在當前串出現過,然後跳parent更新,如果遇到乙個一級出現過了就退出。這樣子可以記錄出每乙個節點有多少個串了。就可以隨便做了。不知道怎麼證明這個複雜度最差是n−

−√n

nlogn

n lo

gn

的題意:現在給定你n個字串,詢問每個字串有多少子串(不包括空串)是所有n個字串中,至少k個字串的子串(注意包括本身)。

題解:廣義字尾自動機就可以了。同意一下每個節點出現在了多少個串裡面。要注意的是,每個節點要累加他父親的答案,因為你範圍更小的區間不在這裡啊。然後有乙個細節我跳了很久,就是我用的是對於新加入的點,跳parent更新這個點出現在了這個串裡面,但是**的時候我沒有把標記一起賦值,這個要注意

題意:求所有字尾,兩兩之間lcp的和

題解::容易想到,把串反過來,就可以變成求所有字首兩兩的最長公共字尾。我們知道,兩個串的最長公共字尾,是mx

(lca

) mx(

lca)

,然後遍歷整棵樹。考慮每個節點可以作為多少點對的lca即可。至於有多少個代表字首的點,每乙個新增(**的不算)的節點都是乙個,直接標記一下就好了

題意:現在有若干組詢問,對於每乙個詢問,我們給出若干個字尾(以其在s中出現的起始位置來表示),求這些字尾兩兩之間的lcp(longestcommonprefix)的長度之和.一對字尾之間的lcp長度僅統計一遍.

題解:和上一題基本上套路是一樣的,但是這個有多個詢問,建立虛樹即可

題意:給定兩個字串,求出在兩個字串中各取出乙個子串使得這兩個子串相同的方案數。兩個方案不同當且僅當這兩個子串中有乙個位置不同。

題解:

方法①:容易想到,如果我們建立廣義字尾自動機,然後對於每乙個節點分別記錄在兩個串裡面出現了多少次,然後乘起來就可以了。

方法②:對於每乙個串分別建立字尾自動機,然後在遍歷他的字典樹,如果對於x這個節點,如果兩顆樹都有y這個兒子,就一起走下去,複雜度是(26

n)( 26n

)題意:每個問題均有a,b,c,d四個引數,問你子串s[a..b]的所有子串和s[c..d]的最長公共字首的長度的最大值是多少?

題解:第一次做這個題的時候,感覺很難,但現在看回來,也不過如此。最長公共字首不是我們喜歡的,於是我們考慮,把串倒過來,那麼就變成字尾了。

考慮二分答案mid

那麼問題就變成了[c

..c+

mid]

[ c.

.c+m

id

]這乙個子串有沒有在[a,b]裡面出現過

考慮找到乙個節點,是的他的max是不小於mid的

這個的話可以用倍增來實現

然後找到這個節點之後,問題就剩下了詢問這個節點的right集合時候有乙個點是屬於[a

...b

] [a.

..b]

線段樹合併即可

題意:給你n個序列,求他們的最長相同子串。相同子串的定義是他們這個子串全部加上某乙個樹可以和另外乙個相同

題解:這題的話,查分一下就變成求最長公共子串了。

題意:給你乙個字串,他只有abcd四種字母。現在要求構造乙個新的字串s,構造的方法是:進行多次操作,每一次操作選擇t的乙個子串,將其加入s的末尾。問你能構造出的所有長度為n的字串s中,構造所需的操作次數最大的字串的操作次數。

題解:先考慮給你構造出來的串,你怎麼求出來次數。乙個顯然的結論就是在sam上面跑,跑到是被就ans++,然後跳回root。這個做法顯然是最優的。於是我們就得到了乙個做法,我們可以預處理出mp

[4][

4]m p[

4][4

],表示從i這個字母開始,一直走走到失配,跳回跟後走到j的最少步數,這個bfs一次就可以出來了。那麼現在得到了乙個4個點的完全圖,問你走不超過n的路徑,最多可以有多少條邊。乙個顯然地貪心想法是中間肯定是很多個環包含在一起,但是貪心的話要討論。我們使用乙個比較無腦的方法。就是二分答案,二分用i條變,最少可以走距離為多少的路徑,這個用倍增floyd可以輕鬆解決,然後就沒有了。

要注意的乙個細節是,我們預處理出的mp,有第一步是需要走第乙個節點的,這個代價不可以漏了,然後一開始因為漏了這個加上二分姿勢不太正確誤打誤撞過了樣例,後來才反應過來

鍊錶複習題

c或者c 實現下面的題目並測試 1.比較順序表和煉表的優缺點,說說它們分別在什麼場景下使用?2.從尾到頭列印單鏈表 3.刪除乙個無頭單鏈表的非尾節點 4.在無頭單鏈表的乙個節點前插入乙個節點 5.單鏈表實現約瑟夫環 6.逆置 反轉單鏈表 7.單鏈表排序 氣泡排序 快速排序 8.合併兩個有序鍊錶,合併...

檔案複習題

1.把乙個數字的list從小到大排序,然後寫入檔案,然後從檔案中讀取出來檔案內容,然後反序,在追加到檔案的下一行中 首先 將list 排序,其次寫入檔案 l 10,8 3,2 6,0 1,9 5,4 l1 sorted l f codecs.open 2.txt wb f.write str l1 ...

網路複習題

廣域網的英文縮寫為 b a.lan b.wan c.pan d.man 下列不屬於計算機網路效能指標的是 d a.rtt b.頻寬 c.吞吐率 d.網路規模 區域網常見的拓撲結構有星型 環型 匯流排型 網路型 樹型 混和型等。乙個網路協議主要由語法 語義 及同步等三要素組成。簡要說明 協議是水平的 ...