#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int M =410000;
char b[M];
int Next[M],ans[M],lb;
void Get_Next()
{
int i=0,k=-1;
Next[0]=-1;
while(i<lb)
{
if(k==-1||b[k]==b[i])
{
Next[i+1]=k+1;
i++;
k++;
}
// bk与bi 失配时
// 因为 next[i]=k next[k]=k'
//所以b1~bk'-1 == bi-k'~bi-1
// 若bk'==bi 则前缀 b1~bk' ==bi-k'~bi成立 则 next[i+1]=k'+1
else
{
k=Next[k];
}
}
}
int main()
{
while(scanf("%s",b)!=EOF)
{
lb=strlen(b);
Get_Next();
// 长度为 1~n 要求后缀(j,n) 1=<j<=n 相等的 前缀个数(1,i) 1<=i<=n
// 如果在 b[n]处失配 利用next[n]=k :"b1~bk-1" ==" bn-(k-1)... bn-1" 如果bk==bn 则得出一解
// 若使 x =next[k] 则 "b1~bx-1" == "bk-1-(x-1)~~ bk-1" == "bn-(x-1) ~~ bn-1"
// 不断时 k=next[k] 直到k为-1为止
int i=0;
int k=Next[lb-1];
while(k!=-1)
{
if(b[k]==b[lb-1])
{
ans[++i]=k+1;
}
k=Next[k];
}
for(int j=i;j>=1;j--)
{
printf("%d ",ans[j]);
}
printf("%d\n",lb);
}
return 0;
}
总结 : next数组的作用 next[j]=k 就是找到与 bj-1 结尾为后缀相等的最长前缀 b1~bx-1