KMP模板:
求next数组
//求next数组
for (int i = 2, j = 0; i <= n; i ++ )
{
while (j && p[j] != p[j + 1]) j = ne[j];
if (p[i] == p[j + 1]) j ++;
ne[i] = j;
}
处理母串
for (int i = 1, j = 0; i <= m; i ++ )
{
while (j && s[i] != p[j + 1]) j = ne[j];
if (s[i] == s[j + 1]) j ++;
if (j == n)
{
}
f[i] == j;
// if (f[i] == n)此时p在s串中第一次出现
}
假设S长度位len,则s存在最小循环节,循环节的长度L为len-ne[len], 子串为s[1, len - ne[n]]
(1)如果len可以被len-ne[len]整除,则表明字符串s完全由循环节循环组成,循环周期为T = len / L
其中L = len - ne[len]
Description Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "abcdef". If we think of concatenation as multiplication, exponentiation by a non-negative integer is defined in the normal way: a^0 = "" (the empty string) and a^(n+1) = a*(a^n). Input Each test case is a line of input representing s, a string of printable characters. The length of s will be at least 1 and will not exceed 1 million characters. A line containing a period follows the last test case. Output For each s you should print the largest n such that s = a^n for some string a. Sample Input abcd aaaa ababab . Sample Output 1 4 3 Hint This problem has huge input, use scanf instead of cin to avoid time limit exceed. Source
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1000010;
int len;
char s[N];
int ne[N];
void work()
{
len = strlen(s + 1);
for (int i = 2, j = 0; i <= len; i ++ )
{
while (j && s[i] != s[j + 1]) j = ne[j];
if (s[i] == s[j + 1]) j ++;
ne[i] = j;
}
int t = len - ne[len];
if (len % t == 0) printf("%d
", len / t);
else puts("1");
}
int main()
{
while (scanf("%s", s + 1))
{
if (s[1] == '.') return 0;
memset(ne, 0, sizeof ne);
work();
}
}