zoukankan      html  css  js  c++  java
  • Lyndon Word & The Runs Theorem

    最近回去啃了啃WC的另一份课件,算是为自己两年前的作品写下续章吧。

    本文是yjz、xyx、csl三人在WC2019营员交流课件的笔记。

    符号和约定

    为了方便本文的叙述,采用如下可能不严谨的定义:
    我们记(w[i:j])表示(w)从第(i)个字符到第(j)个字符组成的子串,当(i=1)(j=|w|)时,(i)(j)可以省略,(i=j)时,可以简记为(w[i])
    对于字符串(u,v),记(ulhd v),如果(u<v)(u)并非(v)的前缀,即两者在结束之前就比较出了大小。
    一个比较显然的结论是,如果(ulhd v),那么对任意字符串(w_1,w_2),有(w_1ulhd w_1v)(uw_1lhd vw_2)

    定义1

    如果字符串(w)满足对于(i=2,3,dots,|w|),都有(w<w[i:]),那么称(w)是一个Lyndon串,即(w)的任意严格后缀都大于(w)本身。

    定理1

    如果(u,v)都是Lyndon串,且(u<v),那么(uv)是Lyndon串。

    证明:将(uv)的后缀((uv)[i:])分为三部分:(iin [2,|u|],i=|u|+1,iin[|u|+2,|uv|])
    对于第一部分,考虑(u)是一个Lyndon串,对于其严格后缀(u[i:]),有(ulhd u[i:]),从而有(uvlhd (uv)[i:])
    对于第二部分,若(ulhd v),则显然(uvlhd (uv)[|u|+1:]);否则(u)(v)的前缀,有([uv<v]Leftrightarrow[v<v[|u|+1:]]),由(v)是Lyndon串,立得后者成立。
    对于第三部分,考虑(uv<v<v[i-|u|:]=(uv)[i:],iin[|u|+2,|uv|])即可。

    定理2

    如果(u)是Lyndon串,设(a)为一个字符,那么对于字符串(u^ku[:i-1]a,iin[1,|u|]),有:
    1.若(a<u[i]),那么(u)是任意以(u^ku[:i-1]a)开头的字符串的最长Lyndon前缀。
    2.若(a>u[i]),那么(u^ku[:i-1]a)是Lyndon串。

    证明:对(a<u[i])的情况,由于(u^nu[:i])若并非(u)本身,就是周期串,不可能是Lyndon串。对于剩下的更长的前缀,不妨假设其为(u^ku[:i-1]av),从而有(u[:i-1]av)作为后缀,由于(u[:i-1]alhd u),因此(u[:i-1]avlhd u^ku[:i-1]av),从而(u^ku[:i-1]av)不可能是Lyndon串。第一部分得证。
    (a>u[i])的情况,将(u^ku[:i-1]a)的严格后缀分为以(u)开头的、以(u)的严格后缀(u[i:])开头的和(a)。对于以(u)开头的,假设其为(u^{k'}u[:i-1]a(k'<k)),由(ulhd u[:i-1]a),立得(u^{k'+1}lhd u^{k'}u[:i-1]a),从而(u^ku[:i-1]a<u^{k'}u[:i-1]a);对于以(u[i:])开头的,由(u[i:]lhd u)立得其小于(u^ku[:i-1]a);最后,由(uleq u[i]<a),即得(a)也大于整个串。因此,(u^ku[:i-1]a)是Lyndon串。

    定义2

    对于字符串(w),若存在一组Lyndon串(u_1,u_2,dots,u_n),满足(w=u_1u_2dots u_n)(u_1geq u_2geq dots geq u_n),那么称(u_1,u_2,dots,u_n)(w)Lyndon分解

    定理3

    任意字符串(w)的Lyndon分解存在。

    证明:采用构造法并对(w)的后缀归纳证明。设(u'_1,u'_2,dots,u'_m)(w[2:])的一组Lyndon分解,由于(w[1])是Lyndon串,有(w=w[1]u'_1u'_2dots u'_m),对于这组“初步的”Lyndon分解,由定理1,只要开头的两个Lyndon串是小于关系,就合并为一个新Lyndon串,反复操作直到只剩下一个串或者是不小于的关系,就得到了(w)的一组Lyndon分解。

    定理4

    任意字符串(w)的Lyndon分解唯一。

    证明:只要证明(w)的任意Lyndon分解的第一个字符串(w[:i])一定是(w)的最长Lyndon前缀,之后考虑余下的串是(w[i+1:])的Lyndon分解,归纳证明即可。
    反证法,假设存在更长的Lyndon前缀(w[:j](i<j)),则该Lyndon分解(w[:i]u_2u_3dots u_n)中,存在一个(u_k)满足其是第一个右端点位置(geq j)的串,不妨记为(w[i':j']),考虑(w[:j])是Lyndon串,因此(w[:i]<w[:j]<w[i':j]leq w[i':j']=u_k),得到(w[:i]<u_k),与Lyndon分解是不递增的矛盾。综上所述Lyndon分解唯一。

    初步的Lyndon分解算法

    在定理4保证了Lyndon分解的唯一性后,定理3实际上给出了一个求Lyndon分解的算法。通过哈希或后缀数组预处理后判断子串的大小关系,并沿用定理3证明中的过程,就可以做到(O(nlog n))求解Lyndon分解。当然,采用( ext{SA-IS})(O(n)-O(1) ext{RMQ})可以使算法做到(O(n)),然而这样的实现并不实用。

    高效的Lyndon分解算法

    通过定理2给我们的启发,有可能找到更好的Lyndon分解算法。考虑将(w)划分为三部分,记录(i,k,p)表示(w[:i])已经进行了Lyndon分解,并确定必定是(w)的Lyndon分解的前若干项,而(w[i+1:k])则是一个形如(u^ku[:j-1])的串,其中(u)是Lyndon串且长度为(p)(w[k+1:])则是未知情况的串。
    考虑不断进行如下迭代,直到(i)变为(|w|)
    考察(w[k+1])(若(k+1>|w|),则定义(w[k+1])是小于任何字符集中字符的特殊字符($)),分三类情况:
    1.(w[k+1]=w[k+1-p]),则(u^ku[:j-1])的形式继续保持,令(k)自增(1)即可。
    2.(w[k+1]>w[k+1-p]),则由定理(2)可知,(w[i+1,k+1])是一个Lyndon串,但是不能保证其一定出现在最终的Lyndon分解中。不过,这仍满足(u^ku[:j-1])的形式((k=j=1)),于是令(k)自增(1),而(p)(k-i+1)即可。
    3.(w[k+1]<w[k+1-p]),则由定理(2)可知,(u)必定是(w[i+1:])的最长Lyndon前缀。由定理4可知,其一定出现在Lyndon分解中,于是我们将(k)(u)全部加入已知的Lyndon分解中。对于剩下的(u[:j-1]),无法保证其满足(u'^ku'[:j-1])的形式,干脆重新开始,令(k)指向(u[:j-1])的第一个字符(单字符必定是Lyndon串),并令(i=k-1,p=1)

    综上即得Lyndon分解,每次迭代是(O(1))的,且(i+k)至少增加(1)。由于(i,kleq |w|),因此整个算法是(O(n))的,并且有非常简洁的实现。

    The Runs Theorem 部分待填坑。

  • 相关阅读:
    leetcode821
    leetcode872
    leetcode700
    leetcode806
    2019-9-2-win10-uwp-右击浮出窗在点击位置
    2019-9-2-win10-uwp-打包第三方字体到应用
    2019-10-18-dotnet-文件读写务必注意事项
    2018-8-10-win10-uwp-如何创建修改保存位图
    2018-8-9-win10-uwp-装机必备应用-含源代码
    2019-11-1-asp-dotnet-core-简单开发P2P中央服务器
  • 原文地址:https://www.cnblogs.com/Mr-Spade/p/14426583.html
Copyright © 2011-2022 走看看