[XSY3320] string (AC自动机,哈希,点分治)
XSY3320
前置芝士:回文前綴&&borderborderborder
推薦博客
推薦博客
考慮點分治,問題變成求經(jīng)過重心的回文路徑個數(shù)。
一條經(jīng)過重心的回文路徑長這樣:
xxx到zzz的串與yyy到rootrootroot的串相同。
建出根到每個節(jié)點對應的串的AC自動機,并在failfailfail樹上找出每個串的回文前綴。判斷根到某個節(jié)點對應的串是不是回文串可以用哈希解決。
根據(jù)borderborderborder理論,一個回文串的所有回文前綴的長度可以組成一個不超過O(logn)O(logn)O(logn)項的等差數(shù)列。即若TkT_kTk?是回文串,TkT_kTk?的最長回文真前綴是Tk?1T_{k-1}Tk?1?,Tk?1T_{k-1}Tk?1?的最長回文真前綴是Tk?2T_{k-2}Tk?2?,…,T2T_2T2?的最長回文真前綴是T1T_1T1?,那么有∣Ti∣=∣Ti?1∣+d|T_i|=|T_{i-1}|+d∣Ti?∣=∣Ti?1?∣+d(ddd為公差)。
考慮一個點作為xxx的貢獻。設根到xxx對應的串為UUU,UUU在AC自動機上對應點XXX。把UUU的最長回文真前綴看成TkT_kTk?,那么TiT_iTi?作為回文串TTT時,我們要查詢有多少個點yyy,滿足根到yyy對應的串是UUU的后綴,且長度為∣U∣?∣Ti∣=∣U∣?∣T1∣?(i?1)d|U|-|T_i|=|U|-|T_1|-(i-1)d∣U∣?∣Ti?∣=∣U∣?∣T1?∣?(i?1)d,記有num[i]num[i]num[i]個符合條件的yyy。那么最后這個xxx的貢獻就是∑i=1knum[i]\sum_{i=1}^{k}num[i]∑i=1k?num[i],換句話說,我們要求有多少個點yyy,滿足根到yyy對應的串是UUU的后綴,且長度lenlenlen符合:len≡∣U∣?∣T1∣(modd),∣U?T1∣≤len≤∣U∣?∣Tk∣len\equiv|U|-|T_1|(\mod d),|U-T_1|\leq len\leq |U|-|T_k|len≡∣U∣?∣T1?∣(modd),∣U?T1?∣≤len≤∣U∣?∣Tk?∣。
UUU的后綴,即XXX在failfailfail樹上的祖先對應的串。我們對failfailfail樹dfsdfsdfs,同時開一個數(shù)組ci,jc_{i,j}ci,j? 記錄當前節(jié)點有多少個祖先(包括自己),滿足該祖先代表的串的長度 modi=j\mod i=jmodi=j。
那么最終貢獻就是dfsdfsdfs到的點代表的串長為∣U∣?∣Tk∣|U|-|T_k|∣U∣?∣Tk?∣時cd,(∣U∣?∣T1∣)moddc_{d,(|U|-|T_1|)\mod d}cd,(∣U∣?∣T1?∣)modd?的值 減去 dfsdfsdfs到的點代表的串長為∣U∣?∣T1∣?d|U|-|T_1|-d∣U∣?∣T1?∣?d時cd,(∣U∣?∣T1∣)moddc_{d,(|U|-|T_1|)\mod d}cd,(∣U∣?∣T1?∣)modd?的值。
但這樣空間復雜度是O(n2)O(n^2)O(n2)的,所以我們考慮分塊,只開到c[n][n]c[\sqrt{n}][\sqrt{n}]c[n?][n?]的大小,對于公差大于n\sqrt{n}n?的,我們暴力跳failfailfail尋找答案。
總結
以上是生活随笔為你收集整理的[XSY3320] string (AC自动机,哈希,点分治)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 倒车入库用打灯吗 科普小知识送给你
- 下一篇: 如何更改无线路由器密码 怎么修改无线路由