题意
传送门 POJ 2752
题解
k m p kmp kmp 中需要维护某一连续子串的最长且相等的前缀与后缀,一般称之为数组 n x t nxt nxt;匹配时 j = n x t [ j ] j=nxt[j] j=nxt[j] 这一步基于一个定理:定义字符串相等的前缀与后缀为 b o r d e r border border;设 r , s r,s r,s 为字符串的 b o r d e r border border,若 ∣ r ∣ < ∣ s ∣ |r|<|s| ∣r∣<∣s∣,则 r r r 为 s s s 的 b o r d e r border border。(证明见此处)
基于 b o r d e r border border 这一性质,反向打印即可,注意 b o r d e r border border 不包括字符串本身,而本题需要考虑。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 400005
char s[maxn];
int res[maxn], b[maxn];
void kmp(const char *s)
{
int i = 0, j = -1, n = strlen(s);
b[i] = j;
while (i < n)
{
while (j >= 0 && s[i] != s[j]) j = b[j];
++i, ++j;
b[i] = j;
}
}
int main()
{
while (~scanf(" %s", s))
{
kmp(s);
int n = strlen(s), i = 0, j = n;
while (j > 0)
{
res[i++] = j;
j = b[j];
}
while (--i >= 0)
{
printf("%d%c", res[i], i ? ' ' : '\n');
}
}
}