Radio Transmissio bzoj-1355
Description
给你一个字符串,它是由某个字符串不断自我连接形成的。 但是这个字符串是不确定的,现在只想知道它的最短长度是多少.
Input
第一行给出字符串的长度,1 < L ≤ 1,000,000. 第二行给出一个字符串,全由小写字母组成.
Output
输出最短的长度.
想法:结论题,输出len-next[len]即可。证明是容易的:
我们假设红色对角线字符子串是我们想要得到的字符串长度。蓝线是题目字符串截至位置。绿色字符串是除去答案字符串的长度。那么我们如何求出答案长度呢?显然,我们用next求出最长前缀后缀,然后相减即可。题目中的最长前缀后缀是上面扩出的两个字符串
最后,附上丑陋的代码... ...
#include <iostream> #include <cstdio> #include <cstring> using namespace std; char s[1001000]; int next[1001000]; int len; void GetNext() { int j=0,k=-1; next[0]=-1; while(j<len) { if(k==-1||s[j]==s[k]) { k++;j++; next[j]=k; } else k=next[k]; } } int main() { scanf("%d",&len); scanf("%s",s); GetNext(); printf("%d\n",len-next[len]); }
小结:KMP的精髓在于数组的灵活应用,而不是KMP本身