• 2020杭电多校(一) Minimum Index(lyndon分解)


    学习完lyndon分解后,我们发现这个分解可以分割字符串并且分割成a[i]>=a[i+1]且每个字符串都是自己的最小后缀

    因此在分解的过程中

    当遇到s[j]==s[k],这说明前面都是循环的字符串,那么答案就是上一个同样位置的答案后移一个循环节长度

    如果s[j]<s[k],这说明马上整串都变成一个lyndon字符串了,因此答案就是开头位置是最小的。

    如果s[j]>s[k]那就说明当前循环节的答案是错误的,不过因为本身在求lyndon字符串的时候,指针就会跳转到当前循环节首位,所以只需要重算一遍就行了

    注意初始化,因为刚开始只有一个字符,因此答案是自身

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int inf=0x3f3f3f3f;
    const int N=1e6+10;
    const int mod=1e9+7;
    const int BAS=1112;
    string s;
    int p[N];
    int f[N];
    int main(){
        ios::sync_with_stdio(false);
        int t;
        cin>>t;
        f[0]=1;
        for(int i=1;i<N;++i) f[i]=1LL*f[i-1]*BAS%mod;
        while(t--){
            string s;
            cin>>s;
            int n=(int)s.size();
            s=" "+s;
            for(int i=1;i<=n;){
                int j=i,k=i+1;
                p[i]=i;
                while(k<=n&&s[j]<=s[k]){
                    if(s[j]<s[k]){
                        p[k]=i;
                        j=i;
                    }
                    else{
                        p[k]=p[j]+(k-j);
                        j++;
                    }
                    k++;
                }
                while(i<=j){
                    i+=k-j;
                }
            }
            ll ans=0;
            for(int i=1;i<=n;++i)
                ans=(ans+1ll*f[i-1]*(p[i]))%mod;
            cout<<ans<<endl;
        }
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    PHP学习笔记(二)
    PHP开发笔记(一)
    PHP NOTE
    python windows进制文件可以直接下载使用
    深入浅出Hyper-V网络虚拟化技术
    深入浅出Hyper-V网络虚拟化(序)
    Windows Server 笔记(七):Windows Server 2012 R2 NIC Teaming(NIC组)
    Hyper-v Server 2012 R2增强会话模式
    Hyper-V动态迁移中?小心性能损失
    CLOUDSTACK FOR HYPER-V
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13384279.html
Copyright © 2020-2023  润新知