首页 > 其他分享 >Lyndon 分解

Lyndon 分解

时间:2023-04-30 16:00:19浏览次数:29  
标签:Word 后缀 uv Lyndon 分解 include

现在只会 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|\ge|v|\),则在 \(|v|\) 前 \(uv\) 和 \(v\) 就出现了不同,则 \(v>uv\),同时 \(v\) 是 Lyndon Word,则 \(uv\) 的所有后缀都大于它。若 \(|u|<|v|\),则若 \(u\) 不是 \(v\) 前缀,则显然 \(v>uv\)。反之,将 \(v\) 前面 \(|u|\) 个字符去掉大于 \(v\) ,则 \(v>uv\)。

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

证明:设 \(sxt\) 是 Lyndon Word,则对于 \(i\ge 2\),\(s[i\rangle xt>sxt\),即 \(s[i\rangle x>s\),因此 \(s[i\rangle y>s\)。而 \(y>x>s_1\),因此 \(sy\) 是 Lyndon Word。

Lyndon 分解

定义:一个串 \(s\) 的 Lyndon 分解为一个字符串序列 \(t_1,t_2,\cdots,t_m\),满足:

  1. \(t_i\) 为 Lyndon Word。
  2. \(t_i\ge t_{i+1}\)。

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

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

唯一性:假设存在两个 Lyndon 分解 \(A,A'\),设 \(|A_i|>|A'_i|\),此时 \(A_i=A'_iA'_{i+1}\cdots A'_k\langle l]\)。那么显然有 \(A_i<A'_k\langle l]\le A'_k\le\cdots\le A'_i<A_i\) 矛盾。

Duval 算法

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

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

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

  1. \(s_j=s_k\) 时,\(j,k\) 都 \(+1\),仍然不变。
  2. \(s_j<s_k\) 时,\(v+s_k\) 是 Lyndon Word,则不断往前合并,整个 \(s[i,k]\) 固定为 Lyndon Word。
  3. \(s_j>s_k\) 时,\(t^x\) 固定为 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;
}

标签:Word,后缀,uv,Lyndon,分解,include
From: https://www.cnblogs.com/gtm1514/p/17365368.html

相关文章

  • Lyndon 小记
    神秘科技。定义一个串为Lyndon串,当且仅当这个串的最小表示法是它本身。定义一个串的拆分为Lyndon分解,当且仅当每个拆分都是Lyndon串,且\(s_i\geqs_{i+1}\)。求出某个串的Lyndon分解可以用Duval算法,该算法可以\(O(n)\)求出这个串的Lyndon分解。这个算法的流程如......
  • 对矩阵乘以矩阵的转置和矩阵进行奇异值分解得到的向量是一样的。
    w=rand(4,6)[Ud,Sd,Vd]=svds(w/6,4)[Ud1,Sd1,Vd1]=svds(w*w'/6,4)发现Ud和Ud1的向量值是一样的,或者是相反的。  ......
  • MATLAB代码:基于benders分解算法的两阶段鲁棒问题求解
    MATLAB代码:基于benders分解算法的两阶段鲁棒问题求解关键词:两阶段鲁棒benders分解法 鲁棒优化参考文档:《Solvingtwo-stagerobustoptimizationproblemsusingacolumn-and-constraintgenerationmethod》(问题背景是这个文献,benders分解过程见CSDN)仿真平台:MATLABYALMIP......
  • 将TDateTime值分解为小时、分钟、秒和毫秒,以及计算时间差
     将时间日期分解procedureTForm1.Button1Click(Sender:TObject);varPresent:TDateTime;Year,Month,Day,Hour,Min,Sec,MSec:Word;beginPresent:=Now;SysUtils.DecodeDate(Present,Year,Month,Day);Label1.Caption:='TodayisDay'+I......
  • 质数和分解
    #include<iostream>#include<string.h>usingnamespacestd;constintN=210;intm;intf[N][N];intprimes[N];intcnt=1;boolst[N];voidinit(){for(inti=2;i<=200;i++){if(!st[i])primes[cnt++]=i;for(intj=1;......
  • HJ82_将真分数分解为埃及分数_数学
    参考高赞答案思路:将真分数分子、分母分别x2。目的使循环:分母除分子余数为0存在。1importsys2a=[]3forlineinsys.stdin:4a.append(line.strip().split("/"))5foriina:6l=[]7a=int(i[0])*28b=int(i[1])*29whilea:10......
  • 奇异值分解(SVD)和图像压缩
    在本文中,我将尝试解释SVD背后的数学及其几何意义,还有它在数据科学中的最常见的用法,图像压缩。奇异值分解是一种常见的线性代数技术,可以将任意形状的矩阵分解成三个部分的乘积:U、S、V。原矩阵A可以表示为:具体来说,A矩阵中的奇异值就是\Sigma矩阵中的对角线元素,它们是矩阵A的......
  • SVD奇异值分解
    1.奇异值分解的原理  以上图形可以表示为: uivi结果为秩1矩阵。  2.奇异值分解的应用(1)图像压缩对角矩阵中奇异值较大的排在前面,这些也是影响最大的因素,因此可以将后面的小奇异值去掉,进行图像压缩   (2)时空矩阵   ......
  • HJ82_将真分数分解为埃及分数_数学
    原文连接:(7条消息)将真分数分解为埃及分数_且_听_风_吟的博客-CSDN博客     1a,b=8,112a=a*103b=b*104res=[]5whilea:6foriinrange(a,0,-1):7print(i,b)8if(b%i==0):9print(i,b,a,r......
  • 奇异值分解在Ax=0中的应用
    奇异值分解在视觉SLAM中的应用手稿,有时间再排版......