zoukankan      html  css  js  c++  java
  • Minimum Index【Lyndon分解】-2020杭电多校1

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=6761

    分析:

    (Lyndon) 分解:
    (Lyndon) 串:对于字符串 (s),如果 (s) 的字典序严格小于 (s) 的所有后缀的字典序,我们称 (s) 是简单串,或者 (Lyndon) 串 。
    性质:任意字符串 (s) 都可以分解为 (s=s_1s_2…s_k),其中 (∀s_i)(Lyndon) 串且 (s_i⩾s_{i+1}),且这种分解方法是唯一的。

    (Duval) 算法:
    该算法可以在 (O(n)) 的时间内求出串 (s)(Lyndon) 分解。
    模板代码-Lyndon 分解

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN = (1 << 21) + 1;
    char s[MAXN];
    int main() {
        scanf("%s", s + 1);
        int N = strlen(s + 1), j, k;
        for(int i = 1; i <= N;) {
            j = i; k = i + 1;
            while(k <= N && s[j] <= s[k]) {
                if(s[j] < s[k]) j = i;
                else j++;
                k++;
            }
            while(i <= j) {
                printf("%d ", i + k - j - 1);
                i += k - j;
            }
        }
        return 0;
    }
    

    代码:

    
    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    const int N=1e6+6;
    const int mod=1e9+7;
    int ans[N];
    char ss[N];
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%s",ss+1);
            int len=strlen(ss+1);
            int i=1;
            ans[1]=1;
            while(i<=len)
            {//重新开始分解
                int j=i,k=i+1;//i是近似串的开始
                while(k<=len&&ss[j]<=ss[k])
                {
                    if(ss[j]<ss[k])//加入到近似的Lyndon串中
                    {
                        j=i;
                        ans[k]=i;
                    }
                    else//继续保持
                    {
                        ans[k]=ans[j]+k-j;
                        j++;
                    }
                    k++;
                }
                while(i<=j)//起点向后移
                    i+=k-j;
                ans[k]=i;//
            }
            ll base=1112,fac=1,res=0;
            for(int i=1;i<=len;i++)
            {
                res=(res+fac*ans[i]%mod)%mod;
                fac=fac*base%mod;
            }
            printf("%lld
    ",res);
        }
        return 0;
    }
    
    

    参考博客:
    https://oi-wiki.org/string/lyndon/
    https://www.cnblogs.com/zwfymqz/p/10198690.html
    https://www.cnblogs.com/st1vdy/p/13362219.html

  • 相关阅读:
    原生js面试题
    ZJOI2017day2退役战
    uoj6
    uoj5
    uoj2
    uoj1
    论逗逼的自我修养之ZJOI2017Day1
    noip2016滚粗记
    统计损失
    珍珠项链
  • 原文地址:https://www.cnblogs.com/1024-xzx/p/13411284.html
Copyright © 2011-2022 走看看