题目链接
http://poj.org/problem?id=1961
分析
KMP算法中定义了 n e x t [ i ] next[i] next[i] 数组来记录对于每个 i i i,满足 j < i j < i j<i 且 s [ 1... j ] = s [ i − j + 1 , i ] s[1 ... j] = s[i - j + 1, i] s[1...j]=s[i−j+1,i] 的最大的 j j j。
前缀 i i i 的最小循环节则是 i − n e x t [ i ] i - next[i] i−next[i],而此题中要求 i − n e x t [ i ] i - next[i] i−next[i] 整除 i i i 且 i i − n e x t [ i ] > 1 {i \over i - next[i]} > 1 i−next[i]i>1。
AC代码
#include <cstdio>
const int maxn = 1e6 + 5;
int n, nxt[maxn];
char s[maxn];
inline void get_nxt() {
for (int i = 2, j = 0; i <= n; ++i) {
while (j && s[j + 1] != s[i]) j = nxt[j];
if (s[j + 1] == s[i]) ++j;
nxt[i] = j;
}
}
int main() {
int id = 0;
while (scanf("%d", &n) == 1 && n) {
printf("Test case #%d\n", ++id);
scanf("%s", s + 1);
get_nxt();
for (int i = 2; i <= n; ++i)
if (i % (i - nxt[i]) == 0 && i / (i - nxt[i]) > 1)
printf("%d %d\n", i, i / (i - nxt[i]));
puts("");
}
return 0;
}