• Lyndon 分解


    Lyndon 分解学习笔记

    定义

    如果串 (s) 的所有后缀 (t) 均大于 (s),那么称 (s) 为 Lyndon 串(Lyndon Word)。显然,这等价于 (s) 为其最小循环表示。

    一个串 (s) 的 Lyndon 分解为将 (s) 拆分为若干部分 (s_1s_2...s_k),满足 (s_i) 为 Lyndon 串,且 (s_1 ge s_2 ge s_3 ge ... ge s_k)

    性质

    • (u,v) 为 Lyndon 串,且 (u<v),则 (uv) 为 Lyndon 串。

    • 一个串的 Lyndon 分解有且仅有一种方案。(当 (s_i < s_{i+1}) 时合并两串得到新 Lyndon 串,一直这么做可得到一种方案)(如果存在多种方案,不妨设 (s_i' = s_i + t),其中 (s_i) 之前部分两种方案一致。那么 (t > s_i'),那么 (s_{i+1} > s_i)

    • 如果 (sc) 可以作为 Lyndon 串的前缀,其中 (|c| = 1),那么对于一个比 (c) 大的字符 (d),有 (sd) 一定是 Lyndon 串。

    • 如果 (s_1) 为 Lyndon 串且 (s_1 > s_2),那么 (s_1 > s_2 + s_2)

    • Lyndon 串不含 border

    构造方法

    因为 Lyndon 分解的限制只在相邻两个 Lyndon 串上,我们只用管最近的 Lyndon 串即可。

    将串 (s) 分为 已经确定好的 Lyndon 串 (A),未确定的(可能出现循环的)串 (B),以及尚未考虑的串 (C)

    假设 (B) 的周期为 (l),每个循环节均为一个 Lyndon 串。如果 (C) 的第一个字符 (s_k)(s_{k-l}) 大,那么可以将 (B)(s_k) 合并成一个 Lyndon 串,周期为 (|B|+ 1)。如果 (C) 的第一个字符 (s_k < s_{k-l}),那么 (B) 中前面所有满的循环节都可以拆出来成为 Lyndon 串了,因为它们不可能继续和 (s_k) 拼一块。如果 (s_k = s_{k-l}),那么我们只好将 (s_k) 加入 (B) 继续观察。

    均摊复杂度为 (O(n))

    for (int i = 1; i <= n; ) {//i:A后面那个位置
    	int j = i, k = j + 1;//j:k-l
    	while (k <= n && s[k] >= s[j]) {
    		if (s[k] == s[j])	++j;
    		else	j = i;
    		++k;
    	}
    	while (i <= j) {
    		Push(i, i + (k-j) - 1);//i...i+k-j-1 为一个 Lyndon 串
    		i += (k - j);
    	}
    }
    

    最小表示

    如何利用 Lyndon 分解求一个串 (s) 的最小表示?

    (ss) 进行 Lyndon 分解,其中开头在 (1...n) 的 Lyndon Word 的开头 (i) 记为最小表示的开头

    因为后面的肯定不行(其实会发现后面好像都成了一大块 Lyndon Word,除了循环串),前面的 Lyndon 串比这个串大的也肯定不行,前面的和它相等的也都可以。

    不过如果前面出现和它相等的 Lyndon Word 的话一定是出现了循环串(如 abab -> abababab)否则后面不可能再分解出 Lyndon 串了,因为分解出的 Lyndon 串必须小于等于前面和它相同的部分的 Lyndon Word,这只有循环串才能实现。

    for (int i= 1; i <= n; ++i)	s[i + n] = s[i];
    int ans = 0;
    for (int i = 1; i <= n; ) {
    	int j = i, k = i + 1; ans = i;
    	while (k <= n + n && s[k] >= s[j]) {
    		if (s[k] == s[j])	++j;
    		else	j = i;
    		++k;
    	}
    	while (i <= j) i += (k - j);
    }
    
  • 相关阅读:
    解决 minicom 不能接收键盘输入问题
    Qt 使用tablib获取多媒体tag信息
    博客园scribefire配置
    Connection Manager简称connman
    【转】使用ssh-keygen和ssh-copy-id三步实现SSH无密码登录
    ubuntu 更改U盘设备分区/dev/sdb4 标识
    Qt 自动化测试Test cutedriver
    在Sublime2/3中使用build命令编译TypeScript文件
    移动端Web适配单位rem的坑
    禁止保存,拖拽图片,禁用右键和F12
  • 原文地址:https://www.cnblogs.com/JiaZP/p/14296459.html
Copyright © 2020-2023  润新知