【算法】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; }