码迷,mamicode.com
首页 > 其他好文 > 详细

P6114 【模板】Lyndon 分解

时间:2020-07-29 21:45:56      阅读:71      评论:0      收藏:0      [点我收藏+]

标签:strlen   style   org   getch   英文字母   位置   ble   pen   题解   

题目描述

这是一道模板题。

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

一个字符串 ss 是一个 \text{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\n", ans);
    return 0;
}

 

 

P6114 【模板】Lyndon 分解

标签:strlen   style   org   getch   英文字母   位置   ble   pen   题解   

原文地址:https://www.cnblogs.com/Yokel062/p/13399276.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!