求循环节长度直接len-f[len]
注意可能循环节长度不超过R,C
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
#define N 100500
int vis[N];
int getfail(char *s,int *f)
{
f[0]=f[1]=0;
int len=strlen(s);
for(int i=1;i<len;++i)
{
int j=f[i];
while(j&&s[j]!=s[i]) j=f[j];
f[i+1]=s[j]==s[i]?j+1:0;
}
return len-f[len]; // 找循环节
}
int gcd(int a,int b)
{
if(!b) return a;
return gcd(b,a%b);
}
int lcm(int a,int b)
{return a/gcd(a,b)*b;}
char str[N],mat[N][100];
int nxt[N];
int main ()
{
int R,C;
while(scanf("%d%d",&R,&C)!=EOF)
{
for(int i=0;i<R;++i)
scanf("%s",mat[i]);
int L1=1,L2=1;
for(int j=0;j<C;++j)
{
for(int i=0;i<R;++i)
str[i]=mat[i][j];
str[R]='\0';
int temp=getfail(str,nxt);
L1=lcm(L1,temp);
}
for(int j=0;j<R;++j)
{
for(int i=0;i<C;++i)
str[i]=mat[j][i];
str[C]='\0';
int temp=getfail(str,nxt);
L2=lcm(L2,temp);
}
if(L1>R) L1=R;
if(L2>C) L2=C;
printf("%d\n",L1*L2);
}
return 0;
}