最小循环节见这里:点击打开链接
最小表示法见这里:点击打开链接
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char s[2000005];
char t[2000005];
char s1[2000005];
int next[1000005];
void get_next(char *s,int *next)
{
int l=strlen(s);
int i=0,j=-1;
next[0]=-1;
while(i<l)
{
if(j==-1||s[i]==s[j])
{
i++;
j++;
next[i]=j;
}
else
j=next[j];
}
}
int minrep(char *s)
{
int l=strlen(s);
int i=0;
int j=1;
int k=0;
while(i<l&&j<l&&k<l)
{
int t=s[(i+k)%l]-s[(j+k)%l];
if(!t)
k++;
else
{
if(t>0)
i=i+k+1;
else
j=j+k+1;
if(i==j)
j++;
k=0;
}
}
int mi=min(i,j);
strncpy(t,s+mi,l);
return mi;
}
int maxrep(char *s)
{
int l=strlen(s);
int i=0;
int j=1;
int k=0;
while(i<l&&j<l&&k<l)
{
int t=s[(i+k)%l]-s[(j+k)%l];
if(!t)
k++;
else
{
if(t<0)
i=i+k+1;
else
j=j+k+1;
if(i==j)
j++;
k=0;
}
}
int mi=min(i,j);
strncpy(t,s+mi,l);
return mi;
}
int main()
{
while(scanf("%s",s1)!=EOF)
{
get_next(s1,next);
int l=strlen(s1);
int time=1;
if(l%(l-next[l])==0)
time=l/(l-next[l]);
printf("%d %d",minrep(s1)+1,time);
printf(" %d %d\n",maxrep(s1)+1,time);
}
return 0;
}
本文详细介绍了最小循环节和最小表示法的高效算法实现过程,包括预处理步骤、核心算法和应用实例。通过使用KMP算法进行前缀匹配,实现了最小循环节的快速查找,并通过循环迭代优化最小表示法的表达形式,为解决字符串重复子串问题提供了一种高效解决方案。
1419

被折叠的 条评论
为什么被折叠?



