zoukankan      html  css  js  c++  java
  • Lyndon 分解

    Lyndon 串

    其严格最小后缀为其本身的串,称为 (Lyndon) 串,也就是 (s) 是其所有循环移位中严格最小的。

    (s,t) 都为 (Lyndon) 串是,且 (s<t),则 (st) 也为 (Lyndon) 串。证明 (t>st) 后即可证明该性质。

    Lyndon 分解

    (Lyndon) 分解为将 (s) 分解得 (s=s_1s_2s_3 dots s_k),且 (s_i geqslant s_{i+1})(Lyndon) 分解是存在且唯一的。

    存在性由 (Lyndon) 串的性质不难得到,唯一性可以用反证法来证明。

    Duval 算法

    (Duval) 算法可以 (O(n)) 求出一个串的 (Lyndon) 分解。

    对于字符串 (s) 和字符 (c),若 (sc) 是某个 (Lyndon) 串的前缀,则对于字符 (d>c)(sd)(Lyndon) 串。

    维护三个指针 (p,i,j)([1,p-1]) 是已经进行完 (Lyndon) 分解的部分,([p,j-1])(s_1s_2s_3 dots s_kt),其中 (t) 可以为空串,且 (s_1)(Lyndon) 串和 (s_1=s_2= dots =s_k)(t)(s_1) 的前缀,满足 (s[p,j-1]) 比上一个分解出的串小。

    当前加入字符 (s_j),令 (i=j-|s_1|),即为 (t) 在循环串对应的位置。进行分类讨论:

    (s_i=s_j) 时,(t) 能继续匹配,让 (i,j) 都向后移动一个位置。

    (s_i<s_j) 时,得 (s[p,j])(Lyndon) 串,将 (i) 移动到 (p)(j) 向后移动一个位置。

    (s_i>s_j) 时,得 (s_1s_2s_3 dots s_k) 为分解后的串,然后继续考虑 (t)(j) 向后移动一个位置。

    因为 (p) 只向后移动,(j) 向前移动的距离不超过 (p) 向后移动的距离,所以复杂度为 (O(n))

    while(p<=n)
    {
        int i=p,j=p+1;
        while(j<=n&&s[i]<=s[j]) i=s[i]==s[j++]?i+1:p;
        while(p<=i) p+=j-i,ans^=p-1;
    }
    

    这段代码求的是 (Lyndon) 分解所有右端点的异或和。

    应用

    求解最小循环表示,(O(n)) 对所有 (s[1,i]) 求最小最大后缀。

  • 相关阅读:
    什么叫TLD、gTLD、nTLD、ccTLD、iTLD 以及几者之间的关系
    socket
    windows下codeblocks报错undefined reference to `WSAStartup@8'|
    Codeforces 467C George and Job | DP
    51Nod 1049最大子段和 | 模板
    51Nod 最大子矩阵和 | DP
    AtomicInteger
    sun.misc.unsafe
    CAS
    java中的四种引用
  • 原文地址:https://www.cnblogs.com/lhm-/p/14122352.html
Copyright © 2011-2022 走看看