2019暑期金華集訓 Day3 字串

2022-05-08 00:00:15 字數 2967 閱讀 2857

考慮字尾樹。

sam的parent樹是反串的字尾樹,所以後面加乙個字元的時候相當於往串前面加乙個字元,恰好多出了乙個字尾。

於是可以以此來理解sam。

每一條路徑對應原串的乙個子串。

每乙個終止節點對應一些字尾。

所有到同乙個點的路徑對應的子串互為字尾,長度連續。

parent樹是反串的字尾樹。

sam可以用來構造sa。(???)

乙個串的本質不同的回文子串的個數是\(o(n)​\)的。

每個點只表示乙個回文串。

sam和回文樹的複雜度都是均攤的,所以不能可持久化。

sam上線段樹合併裸題,直接二分長度然後可以知道\(endpos​\)必須在\([a+len-1,b]​\)裡面,倍增找一下什麼的就沒了。

我們知道\(per_i=i-next_i​\),所以容易想到把kmp可持久化,然而由於kmp複雜度均攤,所以如果直接搞你人就沒了。

我們定義乙個陣列\(trans_​\)表示在\(x​\)後面新加乙個\(c​\)那麼\(next​\)會指到**。設\(s_=c'​\),那麼分兩種情況。如果\(c\ne c'​\),那麼\(trans_=trans_​\),否則\(trans_x=next_x+1​\)。

於是我們發現\(trans_x​\)只會從\(trans_​\)改乙個過來,於是可以可持久化線段樹把複雜度搞到嚴格\(\log n​\),於是就沒了。

另一種方法:考慮\(next_x​\),如果\(next那麼可以放心跳,只會跳\(\log n​\)次。否則,我們發現前\(x​\)位有迴圈節。如果\(c​\)等於對應的那一位那麼就做完了,否則無論如何也不可能匹配上,就可以直接模\(x-next_x​\)。

簡單題。直接在字尾陣列上二分rank最大的字尾的長度,然後變成了有一堆線段,要撒一些點把這些線段切開,貪心即可。

發現\(t_x​\)必須是\(s​\)的子串,否則詢問毫無意義。

於是我們可以直接對\(s​\)建sam,然後後面加字元就是跳\(ch​\),前面就是跳\(parent​\)樹,詢問就線段樹合併然後亂搞即可。

離線,固定右端點。

維護序列\(ans_l​\)表示固定當前右端點的時候左端點為\(l​\)答案多少。

右端點往右一格,會多出很多字尾,相當於sam上節點到根的一條鏈又出現了一遍。

每個節點記錄\(tag_x​\), 表示上一次出現的位置在**。

那麼這一次做出的貢獻就是\(ans[tag_x-len+1,r-len+1]++​\)。

還要注意由於每個節點代表的是一堆字尾,所以其實有某些段加的不是定值,而是關於下標的乙個一次函式。

右移完之後,這一段的\(tag​\)就搞成一樣的了。

注意到這個東西很像lct的access操作,可以直接暴力做,用線段樹維護。

於是總複雜度\(o(n\log^2 n)​\)。

模擬上面的方法,仍然設\(ans_l\)和\(tag_x\),但這次用回文樹做。

然而,這次回文樹的節點表示的回文串長度不連續,就比較噁心了。

但是我們知道:在乙個點結束的回文串的起始位置組成了\(\log n\)個等差數列。

為什麼?考慮最長的那個回文串,其他回文串顯然都是他的border。

有乙個關於border集合的定理:它們組成\(\log n\)個等差數列。

於是我們就得到了這個結論。

然後我就不會了,不知道怎麼就做到\(o(n\sqrt)\)了。

咕了

update:菜雞pb來修鍋了……

熟悉回文樹的人(顯然不包括我)肯定可以看出來,這\(o(\log n)\)個等差數列是很容易拆出來的。

考慮只有乙個等差數列的時候,新加入乙個\(r\)會發生什麼。對於某乙個\(l\),如果他包含了某乙個回文串,那麼比這個串更短的串都不會更新\(l\)的答案了,因為對稱一下之後就已經出現過了。

所以我們看一下最長的那個串上一次在**出現,然後所有原來不包含那個串的\(l\)答案都是加1。

有多個等差數列呢?顯然包含了這一段某乙個串之後更短的串都不會有貢獻,所以可以分開考慮。

上一次出現的位置可以查詢回文樹上的子樹得到。

複雜度\(o(n\log^2 n)\)。

又是一道做過然後又忘掉了的一題。/kk

見部落格。

動態往乙個串後面加字元,加完之後詢問任意兩個字首的最長回文字尾長度。

回文自動機,lcp就是樹上的lca深度。每次向後擴充套件一位就求一下與之前節點的lca的深度之和,用lct維護。

回文樹、回文自動機沒有學好,要注意。

求\[\sum_ [|a|+|b|-2lcp(a,b)

我tm這都沒看出就是兩點距離真是沒救了,我退役算了……

發現每個點代表的距離是一段區間,所以如果點分治的話會比較麻煩。然而,如果上邊分治,那麼這題就沒了。

見部落格。

做過啦……然而還是不會……

首先發現設\(dp_x\)表示從\(x\)開始走公升上天堂的概率,那麼我們應該先選\(dp_x\)大的。

考慮每次轉移都是除以二,所以用二進位制儲存,就變成了乙個trie。

要排序,就是要給trie做乙個sa。

資料範圍太大,不能帶log,考慮字尾自動機轉字尾陣列。

用某種方法建出字尾陣列(咕了)之後就可以統計資訊,還要fft來優化。

複雜度\(o(n+k\log^2 l)\)。

對於字串\(s\),如果\(s\)的最小字尾是他本身,那麼\(s\)就是lyndon串。

這也等價於\(s\)是他迴圈移位中最小的乙個。

如果\(u,v\)是lyndon串,那麼\(uv\)是lyndon串當且僅當\(u。

lyndon分解:任意串\(v\)可以被唯一分解成一堆lyndon串連在一起,而且這些串單調遞減。

存在性顯然,而唯一性:假設從第\(i\)個開始不同,設\(|s_i|<|s'_i|\),然後……已經會證,但不太好說明。

duval演算法,\(o(n)\)搞出lyndon分解:已經會了。

做過啦,會啦……

2019暑期金華集訓 Day7 動態規劃

首先發現這個樹的形態沒啥用,只需要保證度數之和是 2n 2 且度數大於0即可。然後設 dp 表示前 i 個點用了 j 個度數的最小值,然後就獲得了 o n 3 的dp。不妨每個點的度數都減1,那麼總度數就變成 n 2 了。考慮原來 i 的作用是什麼 要限制選的點數不能超過 n 此時我們總度數小於 n...

2019暑期金華集訓 Day6 計算幾何

內積不等式 a,b 2 le a,a b,b 其中 a,b 表示 a cdot b 好像是廢話?a times b a b sin theta 二維叉積 a times b x 1y 2 x 2y 1 三維叉積 a times b left begin i j k ax ay az bx by bz...

2019暑期金華集訓 Day1 組合計數

n le 10 直接暴力列舉。n le 32 meet in the middle,如果左邊選了 x 右邊選了 y 且 x y le b 那麼對答案的貢獻就是 根據範德蒙德恒等式 sum n 所以上面可以拆開成 sum 列舉 x 關於 y 是乙個字首和。如果沒有下界的限制,只有 p i in 0,r...