給定長度 n 字符串,對每個前綴 (長度 i≥2),判斷是否為周期串。是則輸出 i 和最大周期數 K。多測試用例,n=0 結束。
`next[i]` = 長度 i 前綴的最長真前綴兼後綴長度。
定理:前綴長度 i 是周期串 ⟺ `next[i] > 0` 且 `i % (i - next[i]) == 0`。
最小周期長 = `i - next[i]`,最大周期數 K = `i / (i - next[i])`。
#include
#include
const int MAXN = 1000005;
char s[MAXN];
int nxt[MAXN];
void buildNext(const char* s, int n) {
nxt[0] = nxt[1] = 0;
for (int i = 1; i < n; ++i) {
int j = nxt[i];
while (j && s[j] != s[i]) j = nxt[j];
nxt[i+1] = (s[i] == s[j]) ? j + 1 : 0;
}
}
int main() {
int n, cas = 0;
while (scanf("%d", &n) == 1 && n) {
scanf("%s", s);
buildNext(s, n);
printf("Test case #%d\n", ++cas);
for (int i = 2; i <= n; ++i) {
int period = i - nxt[i];
if (nxt[i] && i % period == 0)
printf("%d %d\n", i, i / period);
}
printf("\n");
}
return 0;
}
s = "aabaabaabaab" (n=12)
i=12, nxt[12]=9
period = 12-9=3 ("aab")
K = 12/3 = 4
驗證:"aab" × 4 = "aabaabaabaab" ✓