P6114 模板Lyndon 分解

Posted yokel062

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P6114 模板Lyndon 分解相关的知识,希望对你有一定的参考价值。

题目描述

这是一道模板题。

读入一个由小写英文字母组成的字符串 ss ,请把这个字符串分成若干部分 s=s_1s_2s_3cdots s_ms=s1?s2?s3??sm?,使得每个 s_isi? 都是  ext{Lyndon Word}Lyndon Word,且 forall 1le i<m:s_ige s_{i+1}1i<m:si?si+1?。输出 s_1s1? 到 s_msm? 这些串长度的右端点的位置。位置编号为 11 到 nn。

一个字符串 ss 是一个  ext{Lyndon Word}Lyndon Word,当且仅当 ss 是其所有后缀中最小的字符串。

为了减小输出量,你只需要输出所有右端点的异或和。

输入格式

一行一个长度为 nn 的仅包含小写英文字母的字符串 ss。

输出格式

一行一个整数,表示所有右端点的异或和。

 

题解:https://www.luogu.com.cn/problem/solution/P6114

#include <bits/stdc++.h>
#define IO_read ios::sync_with_stdio(false);cin.tie(0)
#define fre freopen("in.txt", "r", stdin)
#define _for(i,a,b) for(int i=a; i< b; i++)
#define _rep(i,a,b) for(int i=a; i<=b; i++)
#define inf 0x3f3f3f3f
#define lowbit(a) ((a)&-(a))
using namespace std;
typedef long long ll;
template <class T>
void read(T &x)
{
    char c; bool op=0;
    while(c=getchar(), c<0||c>9) if(c==-) op=1;
    x=c-0;
    while(c=getchar(), c>=0&&c<=9) x=x*10+c-0;
    if(op) x=-x;
}
template <class T>
void write(T x)
{
    if(x<0) putchar(-), x=-x;
    if(x>=10) write(x/10);
    putchar(0+x%10);
}

const int maxn=5e6+5;
char s[maxn];

int main()
{
    scanf("%s", s+1);
    int n=strlen(s+1), ans=0;
    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++;
            else j=i;
            k++;
        }
        while(i<=j)
        {
            ans^=i+k-j-1;
            i+=k-j;
        }
    }
    printf("%d
", ans);
    return 0;
}

 

 

以上是关于P6114 模板Lyndon 分解的主要内容,如果未能解决你的问题,请参考以下文章

知识点简单总结——Lyndon分解

知识点简单总结——Lyndon分解

Lyndon分解和最小循环表示学习

hdu6761 Mininum Index // lyndon分解 + duval贪心 + 秦九韶算法

[Lyndon分解] HDU 6761 Minimum Index (2020多校训练)

VSCode自定义代码片段——.vue文件的模板