zoukankan      html  css  js  c++  java
  • OKR-Periods of Words

    https://loj.ac/problem/10046

    题目描述

      定义字符串(Q)为字符串(A)的周期,当且仅当(Q)(A)的前缀(不等于A),且(A)(QQ)的前缀。求所有前缀的最大周期长度之和。

    思路

      我们看数据范围,显然要(O(n))处理,所以我们对每一个前缀都应该用常数级的复杂度找到其最大周期。我们考虑周期的定义,实际上就是要找到一段(Q=A[ 1...len]),并且(A[len+1...n] = Q [1...n-len ]),因此(A[1...n-len]=A[len+1...n]),这就是(KMP)所求的,最长公共前后缀。所以最大周期就是(n-)最短公共前后缀,因为(Q=n-)公共前后缀。所以我们不断(j=p[j]),这样得到最小值就是我们求得最短公共前后缀,答案加上即可。不过由于一步步跳效率会低,我们可以优化,一次跳完直接更新(p)数组。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN=1e6+10;
    char s[MAXN];
    int pre[MAXN];
    int main() 
    {
        int n;
        scanf("%d",&n);
        scanf(" %s",s+1);
        int j=0;pre[1]=0;
        for(int i=1;i<n;i++)
        {
            while(j>0&&s[i+1]!=s[j+1])j=pre[j];
            if(s[i+1]==s[j+1])j++;
            pre[i+1]=j;
        }
        long long ans=0;
        for(int i=1;i<=n;i++)
        {
            j=i;
            while(pre[j])j=pre[j];
            if(pre[i]!=0)pre[i]=j;        //优化 
            ans+=i-j;
        }
        printf("%lld",ans);
        return 0;
    }
    
  • 相关阅读:
    VBA Exit Do语句
    VBA Exit For语句
    VBA Do...While循环
    VBA While Wend循环
    VBA For Each循环
    VBA for循环
    sqoop 教案
    Hbase 取数据 和放数据 使用mr
    Hbase 四种过滤器
    Hbase java API 的方法
  • 原文地址:https://www.cnblogs.com/fangbozhen/p/11788186.html
Copyright © 2011-2022 走看看