版权声明:iQXQZX https://blog.csdn.net/Cherishlife_/article/details/84980933
通过前缀表 求母串的子串的周期循环次数
例题:SDUTOJ2476Period
https://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Contest/contestproblem/cid/2710/pid/2476
AC代码:
#include <bits/stdc++.h>
using namespace std;
#define N 1000001
char s[N];
int nextt[N];
void get_next(char *s)
{
int i = 0, j = -1;
int len = strlen(s);
nextt[0] = -1;
while (i <= len)
{
if (j == -1 || s[i] == s[j])
{
i++;
j++;
nextt[i] = j;
}
else
j = nextt[j];
}
}
int main()
{
int n;
int cnt = 0;
while (~scanf("%d", &n))
{
if (n == 0)
break;
scanf("%s", s);
get_next(s);
cnt++;
printf("Test case #%d\n", cnt);
for (int i = 2; i <= n; i++) // 串的 包含前i个元素的子串的周期循环次数
{
if (i % (i - nextt[i]) == 0 && nextt[i]) // i - nextt[i]为一个周期长度
printf("%d %d\n", i, i / (i - nextt[i]));
}
printf("\n");
}
return 0;
}
例题:SDUTOJ2475 Power Strings
https://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Contest/contestproblem/cid/2710/pid/2475
#include <bits/stdc++.h>
using namespace std;
#define N 1000001
char s[N];
int nextt[N];
void get_next(char *s)
{
int i = 0, j = -1;
int len = strlen(s);
nextt[0] = -1;
while (i <= len)
{
if (j == -1 || s[i] == s[j])
{
i++;
j++;
nextt[i] = j;
}
else
j = nextt[j];
}
}
int main()
{
int n;
int cnt = 0;
while (~scanf("%s", s))
{
if (s[0] == '.')
break;
n = strlen(s);
get_next(s);
if (n % (n - nextt[n]) == 0 && nextt[n]) // 能通过前缀表找到周期 则输出
printf("%d\n", n / (n - nextt[n])); // 输出最大周期循环次数 n - nextt[n]为一个周期长度
else
printf("%d\n", 1); // 如果通过前缀表找不到周期则输出 1
}
return 0;
}