[PKU2406]Power Strings 求构成原串的最短重复子串长度。 KMP的预处理部分即可解决。预处理完,p[len]表示当len匹配失败的时候的回退位置,也就是说p[len]+1..len这部分是构成原串的一个重复子串,子串的长度也就是len-p[len]。题目求的是最多的重复次数,相当于求最短的重复子串,因此答案就是len/(len-p[len])。不过有个特殊点要判断,那就是如果len mod (len-p[len]) != 0,那么原串肯定不是由p[len]+1..len构成的,也肯定不是由任意重复子串连接构成的,因此此时的答案就是1。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <cstdio> #include <cstring> const int MAXLEN(10000001); char s[MAXLEN]; int p[MAXLEN]; int main() { while (scanf("%s", s), s[0] != '.') { p[0] = -1; int len = strlen(s); for (int i = 0, j = -1; i < len-1; ++i) { for (; j > -1 && s[j+1] != s[i+1]; j = p[j]); if (s[j+1] == s[i+1]) ++j; p[i+1] = j; } int sublen = len-1-p[len-1]; if (len % sublen) printf("%dn", 1); else printf("%dn", len/sublen); } }