回文樹學習小結

2021-07-11 06:59:42 字數 1596 閱讀 5432

最近突然撿起了好久不搞的字串,研究了一下一直覺得很神奇的回文樹。

相比於manacher,回文樹要顯得強大的多,同樣是接近o(n)的複雜度,

回文樹只需要多一點的空間,就可以實現許多用manacher實現起來非常複雜的功能。

並且就**量而言,回文樹也足夠的簡短,作為處理回文串的工具,實在是非常的美妙。

做了這麼多回文樹的題,可以發現幾點回文樹的妙用以及稍稍的優化策略。

大概有一下幾點,

節點數減2是本質不同的回文子串數量。

統計全部回文子串可以考慮先記錄每個點的cnt,到最後向拓撲排序一樣往fail(字尾匹配失敗指標)對應的節點累加。

然後是動態在字串末尾加入字母和刪除的操作,因為回文樹每次加入,改變的是last指標的位置,以及是否新加入乙個節點,

可以另開乙個last陣列來儲存之前的位置,以及乙個flag陣列來記錄新加入的點和邊,退回的時候還原last,並且刪邊刪點即可。

還有另外一種前後都可以加字母的操作,這種的話就是為前後開兩個last來記錄位置,因為是回文串,所以左右是相同的,

那麼fail指標是通用的,唯一的乙個需要注意的地方是當整個串是回文的時候要把前後兩個last合併在一起。

最後是另加新邊的問題,目前只遇到過需要加一條half邊的,也就是fail的乙個變種,可以用類似方法構造。

有時候,回文樹是沒辦法開出足夠的陣列來存邊的,那麼可以用鍊錶來建邊,以時間來換空間,其實相應的,該方法同樣可以用於

ac自動機和字尾自動機,當然,既然可以用煉表來存,那麼同樣的,平衡樹其實要更好一些,不過這樣問題就顯得複雜一些了。

在hust上掛了一場test,上述的各種問題其中都可以見到,點我

稍微一提,關於回文,本人的一點想法,

上述的各種問題,其實相互之間都沒有衝突,那麼考慮乙個這樣的問題,

維護乙個雙端佇列,每次可以加入和刪除乙個int範圍的數字,詢問當前狀態下的回文子串數量(本質相同以及不同兩種的)

這個問題相當於融合了上述的各種要點,如果操作次數達到1e6,那麼問題就有些**了。

不過如果能夠掌握上述的內容,還是可以搞定的。估計**要寫個150行左右吧。

另乙個問題是給出多個字串,在給定乙個匹配串,求匹配串和給出的多個字串的最長公共回文子串。

這裡,其實可以把回文樹當做是ac自動機一樣來用,同樣有tire樹和fail指標,那麼稍作修改就可以了。

貌似目前還沒有看到哪個oj有這兩個問題,或者是我做題不夠多吧。

struct linklist

void clear(int x)

int get(int x, int y)

return 0;

}//返回next[x][y]

void insert(int x, int y, int z)

//相當於next[x][y]=z;

};struct palindromictree

int node(int length)

int getfail(int x, int k)

int add(char pos, int k) //k表示型別,0為從前端插入,1為從後端插入

return cnt[last[k]];

}}solve;

回文樹學習小記

回文樹,顧名思義,用回文串構成的一棵樹,結合了一點ac自動機的思想,打起來不長,用起來挺方便。變數 首先滿足ac自動機的結構。定義集合tree fail 指向該節點表示的回文串最長回文字尾在樹中的節點,如abbba就是ababbabbba的最長回文字尾 son 26 表示在當前節點表示的回文串兩邊都...

虛樹學習小結

其實虛樹這東西 不知道說什麼好 簡單易學呃 虛樹主要處理一種詢問總點數不超過o n 且每次詢問的那些點,在預處理之後,所求的值,只和他們,以及他們兩兩的lca有關 這裡有個顯然的結論,即m個點兩兩的lca不超過m 1個,將這m個點按dfs序排序之後相鄰兩點的m 1個lca就是這m個點兩兩的lca 建...

平衡樹學習小結

最近系統的學習了學習平衡樹 splay 現做如下總結。簡而言之,平衡樹是一種二叉樹。何為平衡呢?平衡樹的 平衡 是由於他的深度較為平衡,一般穩定在log級別。平衡樹因其 平衡 而保證了時間複雜度,減少了被卡的概率。我們如何操作呢?利用乙個性質 平衡樹因為中序遍歷是有序的,所以他的左子樹的所有元素都比...