Lyndon Word相關


Lyndon Word

定義

對於字符串 \(S\),若 \(S\) 的最小后綴為其本身,那么稱 \(S\)\(\text{Lyndon}\) 串(\(\text{Lyndon Word}\)

\[S \in L \Rightarrow \begin{cases} S是嚴格最小循環 \\ minsuf(s)=s \end{cases} \]

性質

\(Border(S)=\varnothing\)

推論

如果 \(u,v \in L, u \prec v\Rightarrow uv \in L\)

\(\mathcal{Proof.}\)

\(1) s=u'v,u\triangleleft u' \Rightarrow uv < u'v\)

\(2) \text{to prove uv<v}\)

\(2.1) u \triangleleft v \Rightarrow uv<v\)

\(2.2) u \sqsubseteq v \Rightarrow v=uv',v<v' \Leftrightarrow uv<uv' \Leftrightarrow uv<v\)

\(3) S=v',uv<v<v'\)

\(Q.E.D.\)

PS: \(\triangleleft\):嚴格小於,且不是前綴,必有一個字母不同,\(\sqsubseteq\):前綴

\(ex.\) 如果 \(u,v\in L,u<v \Rightarrow u^av^b\in L\)

顯然。

Lyndon 分解 (Lyndon Factorization)

任意字符串 \(s\) 可以分解為 \(s=s_1s_2s_3\dots s_k\),其中 \(s_i\)\(\text{Lyndon}\) 串,\(s_i \ge s_{i+1}\),且這種分解方法是唯一的。

\(\mathcal{Proof.}\)

先證存在性

初始時每段一個字符,然后不斷地將相鄰兩段 \(s_i<s_{i+1}\) 合並。

再證唯一性

若有兩種方案,取第一次不同的位置,設 \(|s_i| > |s_i'|\),令 \(s_i=s_i's_{i+1}' \dots s_k'pre(s_{k+1}',l)\),則

\[s_i<pre(s_{k+1}',l)\le s_{k+1}' \le s_i' < s_i,矛盾 \]

性質

  1. \(s_k\) 是最長的 \(\text{Lyndon suffix}\)
  2. \(s_1\) 是最長的 \(\text{Lyndon prefix}\)
  3. \(s_k=minsuf(s)\)

\(\mathcal{Proof.}\)

畫圖比划一下,容易(是真的)證得。

Duval 算法

\(\text{Duval}\) 算法可以 \(O(n)\) 時間 \(O(1)\) 額外空間內求出 \(s[1\dots n]\)\(\text{Lyndon}\) 分解。

\[CFL(s)=s_1 s_2 \dots s_k, s.t. \begin{cases} 1. s_i \in L \\ 2. s_1 \ge s_2 \ge \dots \ge s_k\end{cases} \]

\(\mathcal{Lemma.}\)

若字符串 \(v\) 和字符 \(c\) 滿足 \(vc\) 是某個 \(\text{Lyndon}\) 串的前綴,則對於字符 \(d>c\)\(vd\)\(\text{Lyndon}\) 串。

也就是說,如果 \(uav \in L\),那么對於 \((uav)^kua'\)

  1. 如果 \(a<a'\),那么 \((uav)^kua' \in L\)

  2. 如果 \(a>a'\),那么 \(\forall w,(uav)^kua'w \notin L\)

    \(\Rightarrow CFL[(uav)^kua'w]=(uav)^kCFL(ua'w)\)

因此,我們考慮下面這個算法過程:

用三個循環變量 \(i,j,k\) 維持一個循環不變式:

  • \(s[1 \dots i-1] = s_1 s_2 \cdots s_g\) 是已經固定下來的分解,滿足 \(s_l\)\(\text{Lyndon}\) 串,且 \(s_l \le s_{l+1}\)
  • \(j-i\) 是當前最長的 \(\text{Lyndon prefix}\) 的長度,即 \(s[j]\)\(s[k]\)\(\text{Lyndon Prefix}\) 中對應位置的字符。
  • \(k\) 是當前讀入的字符的位置。

然后對於當前讀入的字符 \(a\)

  • \(a>s[j]\),則令直接令 \(s[i\dots k]\) 成為新的 \(\text{Lyndon Prefix}\)
  • \(a=s[j]\),無法切割出新的划分,繼續讀入
  • \(a<s[j]\),則遞歸求解,先分解完 \(s[i\dots t]\) ,即 \((uav)^k\),然后將指針指向 \(t+1\) 重新進行算法過程。

Code

int i, j, k;
for (i = 1; i <= N; ) {
	for (k = i, j = k + 1; j <= N && s[j] >= s[k]; ++j) {
		if (s[j] > s[k]) k = i;
		else ++k;
	}
	while (i <= k) { lyndon[++cnt] = i + j - k - 1; i += j - k; }
}

"Runs" Theorem

先丟一個論文鏈接:The" Runs" Theorem

Lyndon Array

再說。

[ZJOI2017] 字符串

Description

維護一個動態字符串 \(s[1\dots n]\),字符串的字符集是所有 \(|x|\le 10^9\) 的整數。要求支持兩個操作:

  1. 輸入 \(l,r,d\),對於所有 \(l\le i \le r\),將 \(s[i]\) 修改為 \(s[i]+d\)注意 \(d\) 可能是負數
  2. 輸入 \(l,r\),輸出子串 s\([l\dots r]\)字典序最小的后綴的起點位置。即,如果最小后綴是 \(s[p\dots r],(l\le p\le r)\),請輸出 \(p\)

Solution


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM