【BZOJ1921】【CTSC2010】珠寶商(點分治,後綴自動機)

【BZOJ1921】【CTSC2010】珠寶商(點分治,後綴自動機)

題面

洛谷
BZOJ權限題spa

題解

若是要咱們作暴力,顯然能夠以某個點爲根節點,而後把子樹\(dfs\)一遍,建出特徵串的\(SAM\),就能夠直接計算出現次數了。複雜度是\(O(size^2)\)
另一種暴力是咱們枚舉以某個點爲中心,考慮在其兩棵不一樣子樹內各選擇一條鏈,而後拼接在一塊兒計算答案。咱們假設選擇了\(R\)爲中心,而後有一條\((u\rightarrow R)\)的鏈,有一條\((R\rightarrow v)\)的鏈,咱們把\((u\rightarrow R)\)這個串在每一個匹配到的結尾位置打上一個標記,把\((R\rightarrow v)\)這個串在每一個被匹配到的開頭位置打上一個標記,因而咱們就只須要把每一個位置的左右兩個標記乘起來就是答案了。
而後考慮怎麼打這個標記,對於在開頭位置打標記,顯然是匹配上了一個後綴的前綴,那麼咱們把後綴樹建出來,由於每個後綴上的一個葉子節點對應着一個後綴,這樣子咱們只要在後綴樹上找到這個串匹配的節點,而後其子樹的全部葉子節點對應的後綴的開頭位置都要\(+1\),因而子樹加能夠變成在後綴樹上的匹配點單點加,最後一次\(dfs\)一次後綴樹就行了。相似的,在結尾位置打標記就是在前綴的一段後綴打標記,那麼建出前綴樹就好了。因而咱們就能夠作到\(O(m+size)\),其中\(m\)是特徵串的長度。可是這樣子會出現\(R\)的相同子樹裏的一個從上往下的串和一個從下往上的串進行了匹配,因而咱們還要對於每個子樹進行去除。
如今有了這兩種複雜度不一樣的作法,顯然咱們能夠按照\(B=\sqrt m\)來分類討論,對於\(size\le B\)直接\(O(size^2)\)暴力,不然對應下面這種的\(O(m+size)\)的作法,注意對於容斥減去相同子樹內的貢獻的時候,也須要考慮使用兩種對應的方法,不然複雜度是假的。
upd:
補一下關於複雜度的證實:
對於第一類暴力,單次是\(O(size^2)\)的,由於這樣處理完以後全部子樹的答案已經貢獻完畢,能夠直接返回,因此只須要在分治子樹大小第一次小於\(B\)的時候統計答案,而後由於全部這樣的子樹兩兩不交,因此\(\sum size\)是不會超過\(n\)的,而\(\sum size^2\le \frac{n}{B}B^2=nB\),因此這一部分的複雜度是\(O(nB)\)的。
對於第二類暴力,咱們考慮\(size\gt B\)的分治重心的個數,根據點分治的性質,沒有子樹的\(size\)會大於父親的一半,因此每次向上至少要合併兩個\(size\gt B\)的分治子樹,而這樣子的子樹不會超過$ \frac{n}{B}\(個,因此向上合併的次數不會超過\)\frac{n}{B}$次,因此這樣子的分治重心的個數不會超過\(2\frac{n}{B}\),而這樣子單次複雜度是\(O(size+m)\),因此這部分的總複雜度是\(O(\frac{n}{B}m)\)
綜上\(\frac{n}{B}m=nB\),即\(B=\sqrt m\)的時候複雜度最優,爲\(O((n+m)\sqrt m)\)get


代碼被我咕咕咕了怎麼辦......class

相關文章
相關標籤/搜索