POJ 2752
KMP中的next起到了至关重要的作用,在本题中,就是对于KMP这一核心构件的理解
说穿了,KMP中next数组一个很巧妙的地方在于不要在同一个地方跌倒两次
但是对于这道题,如果直接使用next是不符合提议的,单纯使用next会导致我们丢失一部分解(测试样例里面的aaaaa就是个好例子),因此,对于此题我的想法是另开一个数组来记录。
KMP的next我利用kn记录,kn仍然有效,因为事实上在构件KMP所需的数组时,本身就是一个递归应用KMP思想的过程,kn的存在会加速我们的迭代构建过程
#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <stack>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxl= 4e5+6;
char s[maxl];
int l, ans[maxl], n[maxl], kn[maxl];
void PreKmp(char *x, int l, int *n)
{
int i= 0, j= -1;
while (i< l){
while (j> -1 && x[i]!= x[j]){
j= kn[j];
}
++i;
++j;
n[i]= j;
kn[i]= x[i]== x[j] ? kn[j] : j;
}
}
int main(int argc, char const *argv[])
{
while (~scanf("%s\n", s)){
memset(kn, -1, sizeof(kn));
memset(n, -1, sizeof(n));
memset(ans, 0, sizeof(ans));
l= strlen(s);
PreKmp(s, l, n);
int i= l, j= 0;
while (i> 0){
ans[j++]= i;
i= n[i];
}
while (j> 0){
--j;
if (!j){
printf("%d", ans[j]);
}
else{
printf("%d ", ans[j]);
}
}
putchar('\n');
}
return 0;
}