P4391 [BOI2009]Radio Transmission

描述:

  给你一个字符串,它是由某个字符串不断自我连接形成的。 但是这个字符串是不确定的,现在只想知道它的最短长度是多少.

输入格式:

  第一行给出字符串的长度,1 < L ≤ 1,000,000.

  第二行给出一个字符串,全由小写字母组成.

输出格式:

  输出最短的长度

思路:

  比 KMP 模板还要水的一道题目,只要知道字符串的最短循环长度 = l - fail [ l ] 。(l 为字符串的长度),这个公式可以根据 fail 数组的定义得出:因为 fail 数组指的是以该位置为前缀的字符串的最大前后缀的长度。 所以我们假设重复的最小单元为 x ,那么对于任意的以 x 为最小重复单元字符串都可以用 xx...xxx 这样的形式来表示,那么用 l - fail [ l ] 得到的值即为最小的重复单元长度。

标程:

#include<bits/stdc++.h>
using namespace std;
#define maxn 1000005
int l;
char s[maxn<<1];
int fail[maxn<<1];
int main()
{
    scanf("%d",&l);
    scanf("%s",s+1);
    int j=0;
    for(int i=2;i<=l;i++)
    {
        while(j>0&&s[i]!=s[j+1]) j=fail[j];
        if(s[i]==s[j+1]) j++;
        fail[i]=j;
    }
    printf("%d",l-fail[l]);
return 0;
}

 

posted @ 2018-09-27 18:53  落笔映惆怅丶  阅读(151)  评论(0编辑  收藏  举报