zoukankan      html  css  js  c++  java
  • P6114 【模板】Lyndon 分解

    题目描述

    这是一道模板题。

    读入一个由小写英文字母组成的字符串 ss ,请把这个字符串分成若干部分 s=s_1s_2s_3cdots s_ms=s1s2s3sm,使得每个 s_isi 都是  ext{Lyndon Word}Lyndon Word,且 forall 1le i<m:s_ige s_{i+1}1i<m:sisi+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;
    }
  • 相关阅读:
    P1280 尼克的任务
    P2286 [HNOI2004]宠物收养场
    筛法求素数
    拓扑排序
    观光旅游
    [USACO09OCT]热浪Heat Wave
    Java环境变量配置
    git 常用命令
    mysql-5.7安装、配置
    maven-java包管理工具-01
  • 原文地址:https://www.cnblogs.com/Yokel062/p/13399276.html
Copyright © 2011-2022 走看看