迴文樹介紹

迴文樹例題看這 : 點擊

簡介


  咱們知道,Manacher算法能夠在[Math Processing Error]O(n)的時間內求出以每一個位置爲中心的最長迴文串(雖然我昨天還不知道Manacher算法是怎麼作的)。可是若是要統計迴文串的個數,Manacher就捉襟見肘了。因而,迴文自動機閃亮登場!
  迴文自動機是解決迴文串問題的一類數據結構。
  這個數據結構比較新,是由來自戰鬥民族的MikhailRubinchik在2014年的Petrozavodsk夏令營提出。(http://codeforces.com/blog/entry/13959)
  迴文樹實際上是兩棵樹,分別是偶數長度的迴文樹和奇數長度的迴文樹,樹中每個節點表明一個迴文串。
  而回文自動機的方法與Manacher迥乎不一樣,反倒與KMP和AC自動機相似,因此若是你不會Manacher,也沒必要像我同樣去學。html

 

前置技能


  KMP、AC自動機。算法

數聽說明


len[i]:節點i的迴文串的長度
next[i][c]:節點i的迴文串在兩邊添加字符c之後變成的迴文串的編號(和字典樹的next指針相似)
fail[i]:相似於AC自動機的fail指針,指向失配後須要跳轉到的節點(即爲i的最長迴文後綴且不爲i)
cnt[i]:節點i表示的迴文串在S中出現的次數(建樹時求出的不是徹底的,count()加上子節點之後纔是正確的)
num[i]:以節點i迴文串的末尾字符結尾的但不包含本條路徑上的迴文串的數目。(也就是fail指針路徑的深度)
last:指向以字符串中上一個位置結尾的迴文串
cur: 指向由next構成的樹中當前迴文串的父親節點(即當前迴文串是cur左右兩邊各拓展一個字符得來)
S[i]:第i次添加的字符
p:添加的節點個數
n:添加的字符個數數據結構

分析


  假設如今咱們有串S=’abbaabba’。
  先建兩個樹根,偶數長度的根爲0,奇數長度的根爲1。注意,咱們將len[0]設爲0,但將len[1]設爲-1。將p、n、last均初始化爲0。將S[0]設爲-1,這是放一個字符集中沒有的字符,減小特判。而後,咱們將fail[0]指向1。
  舉個例子,如有串S=’abbaabba’。
  首先咱們添加第一個字符’a’,S[++ n] = ‘a’,而後將cur賦爲get_fail(last)。其中的get_fail函數就是讓找到第一個使得S[n-len[last]-1]==S[n]的last。注意,此處的n不爲get_fail中的參數,依然爲添加的字符個數。這樣作的話,咱們就能夠經過fail構成的失配鏈找到last的全部迴文後綴(包括它本身),而後從長到短依次判斷此後綴的前一位是否等於S[n],等於則代表能夠構成一個迴文串。
  判斷此時next[cur][‘a’]是否已經有後繼,若是next[cur][‘a’]沒有後繼,咱們就進行以下的步驟:
  新建節點(節點數p++,且以後p=3),並讓now等於新節點的編號(now=2),則len[now]=len[cur]+2(每個迴文串的長度老是在其最長子迴文串的基礎上在兩邊加上兩個相同的字符構成的,因此是+2,同時體現出咱們讓len[1]=-1的優點,一個字符自成一個奇迴文串時迴文串的長度爲(-1)+2=1)。
  而後咱們讓fail[now]=next[get_fail ( fail[cur] )][‘a’],即獲得fail[now](此時爲fail[2] = 0)。計算get_fail(fail[cur])是爲了求出在cur的全部迴文後綴中(不包括它本身,由於和AC自動機同樣,fail[now]不能指向now),知足前一位等於S[n]的後綴,咱們便可用它來往兩邊拓展一格,即爲now的最長迴文後綴(不包括它本身)。而後next[cur][‘a’] = now。
  當上面步驟完成後咱們讓last = next[cur][‘a’](無論next[cur][‘a’]是否有後繼),而後cnt[last] ++。
  如上述方法插完全部字符後,咱們將節點x在fail指針樹中將本身的cnt累加給父親,從葉子開始倒着加,最後就能獲得串S中出現的每個本質不一樣(兩個串長度不一樣或者長度相同且至少有一個字符不一樣即是本質不一樣可使用burnside引理)迴文串的個數。
  構造迴文樹須要的空間複雜度爲[Math Processing Error]O(N∗字符集大小),時間複雜度爲O[Math Processing Error](N∗log(字符集大小)),這個時間複雜度比較神奇。若是空間需求太大,能夠改爲鄰接表的形式存儲,不過相應的要犧牲一些時間。ide

功能

求串S前綴0~i內本質不一樣迴文串的個數
求串S內每個本質不一樣迴文串出現的次數
求串S內迴文串的個數(其實就是1和2結合起來)
求如下標i結尾的迴文串的個數

函數

相關文章
相關標籤/搜索