Lyndon 分解

现在只会 lyndon 分解怎么写。所以先放在这里占坑。以后补 Runs 和 Lyndon Tree 相关知识。

大量抄 pdf 和 cmd 博客。

Lyndon Word 及其相关性质

定义:若字符串 s 的最小后缀是它本身,则它是一个 Lyndon Word。

  1. Lyndon Word 没有 Border。

证明:如果存在,则 border 作为后缀比它小。
2. 若两个字符串 u,v 为 Lyndon Word,且 u<v,则 uv 也是 Lyndon Word。

证明:首先显然开头在 |u| 前的后缀都比 uv 大。若 |u||v|,则在 |v|uvv 就出现了不同,则 v>uv,同时 v 是 Lyndon Word,则 uv 的所有后缀都大于它。若 |u|<|v|,则若 u 不是 v 前缀,则显然 v>uv。反之,将 v 前面 |u| 个字符去掉大于 v ,则 v>uv

  1. 若字符串 s 和字符 x 满足 sx 为某个 Lyndon Word 的前缀,则对 字符 y>xsy 是 Lyndon Word。

证明:设 sxt 是 Lyndon Word,则对于 i2s[ixt>sxt,即 s[ix>s,因此 s[iy>s。而 y>x>s1,因此 sy 是 Lyndon Word。

Lyndon 分解

定义:一个串 s 的 Lyndon 分解为一个字符串序列 t1,t2,,tm,满足:

  1. ti 为 Lyndon Word。
  2. titi+1

定理:Lyndon 分解存在且唯一。

存在性:构造即证明。初始令 m=|s|,每一个 ti 都是单字符。每次找到 ai<ai+1 并合并为一个串,最后停止的时候即是合法的 Lyndon 分解。

唯一性:假设存在两个 Lyndon 分解 A,A,设 |Ai|>|Ai|,此时 Ai=AiAi+1Akl]。那么显然有 Ai<Akl]AkAi<Ai 矛盾。

Duval 算法

Duval 算法可以在 O(n) 时间复杂度和 O(1) 的额外空间内求得一个串的 Lyndon 分解。它维护三个变量 i,j,k,满足任意时刻:

  • si] 的 Lyndon 分解已经固定。
  • s[i,k1]=tx+v(x>1) 的分解没有固定,t 是 Lyndon Word,且 Lyndon 分解确定的上一个串 tg>s[i,k1]j=k|t|

当前处理到 k,分三种情况讨论:

  1. sj=sk 时,j,k+1,仍然不变。
  2. sj<sk 时,v+sk 是 Lyndon Word,则不断往前合并,整个 s[i,k] 固定为 Lyndon Word。
  3. sj>sk 时,tx 固定为 Lyndon Word,i 调整至 v 的开头。

显然三个指针都是单调的,因此复杂度 O(n)

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char s[5000010];
int n,ans;
int main(){
	scanf("%s",s+1);n=strlen(s+1);
	for(int i=1;i<=n;){
		int j=i,k=i+1;
		while(k<=n&&s[j]<=s[k]){
			if(s[j]<s[k])j=i;
			else j++;
			k++;
		}
		while(i<=j){
			ans^=i+k-j-1;
			i+=k-j;
		}
	}
	printf("%d\n",ans);
	return 0;
}
posted @   gtm1514  阅读(39)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示