【BZOJ】1355 [Baltic2009]Radio Transmission

【算法】KMP

【题解】KMP中n-next[n]得到最小循环节的性质

考虑一个循环串(最后一个循环节可能残缺),它最长的【后缀=前缀】一定是以第二个循环节为起始位置的后缀。

正着考虑的话假设后缀T以x+1开始,S为前缀那:

1.S(1~x)=T(1~x)即S(x+1~2x)

2.S(x+1~2x)=T(x+1~2x)即S(2x+1~3x)。

这样叠加到最后就是循环串了。

注意:

1.当fail[n]=0的时候,循环节默认为自身要判否。

2.n/(n-fail[n])表示循环次数,不能整除说明循环节残缺。

#include<cstdio>
const int maxn=1000010;
char s[maxn];
int n,p[maxn];
int main()
{
    scanf("%d%s",&n,s+1);
    int j=0;p[1]=0;
    for(int i=2;i<=n;i++)
     {
         while(j>0&&s[j+1]!=s[i])j=p[j];
         if(s[j+1]==s[i])j++;
         p[i]=j;
     }
    printf("%d",n-p[n]);
    return 0;
}
View Code

 

posted @ 2017-03-26 12:46  ONION_CYC  阅读(191)  评论(0编辑  收藏  举报