Time limit 3000 ms
Memory limit 65536 kB
Given two strings a and b we define ab to be their concatenation. For example, if a = “abc” and b = “def” then ab = “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.
题目分析
首先上结论
若
n
m
o
d
  
(
n
−
n
x
t
[
n
]
)
=
=
0
n \mod (n-nxt[n])==0
nmod(n−nxt[n])==0,则
a
n
s
=
n
/
(
n
−
n
x
t
[
n
]
)
ans=n/(n-nxt[n])
ans=n/(n−nxt[n]),否则
a
n
s
=
1
ans=1
ans=1
然后开始证明
首先模拟
K
M
P
KMP
KMP匹配
n
x
t
[
n
]
nxt[n]
nxt[n]的情景
图中蓝色部分是匹配部分,即长度
n
x
t
[
n
]
nxt[n]
nxt[n]的前/后缀,橙色部分则是长度
n
−
n
x
t
[
n
]
n-nxt[n]
n−nxt[n]的前缀
把长度
n
−
n
x
t
[
n
]
n-nxt[n]
n−nxt[n]的前缀在下面这部分也表示出来为黄色部分
而与这一部分相匹配的是绿色这一部分
类似的将长度
2
∗
(
n
−
n
x
t
[
n
]
)
2*(n-nxt[n])
2∗(n−nxt[n])的前缀在下面的串上表示出来为黄+紫一块
对应到匹配部分就是绿加粉一部分
依次类推知道长度
n
−
n
x
t
[
n
]
n-nxt[n]
n−nxt[n]的前缀子串是不断循环的
若
n
m
o
d
  
(
n
−
n
x
t
[
n
]
)
=
=
0
n \mod (n-nxt[n])==0
nmod(n−nxt[n])==0,则证明
n
/
(
n
−
n
x
t
[
n
]
)
n/(n-nxt[n])
n/(n−nxt[n])次循环后恰好就是整个串
而KMP求得的
n
x
t
[
n
]
nxt[n]
nxt[n]得长度是尽量长的,所以循环节
n
−
n
x
t
[
n
]
n-nxt[n]
n−nxt[n]一定达到最小,循环次数一定最多
n
−
n
x
t
[
n
]
n-nxt[n]
n−nxt[n]已经达到尽量小,
所以若
n
m
o
d
  
(
n
−
n
x
t
[
n
]
)
̸
=
0
n \mod (n-nxt[n])\not=0
nmod(n−nxt[n])̸=0,一定也有
n
m
o
d
  
(
n
−
n
x
t
[
n
x
t
[
n
]
]
)
̸
=
0
n \mod (n-nxt[nxt[n]])\not=0
nmod(n−nxt[nxt[n]])̸=0,以此类推
最后答案只能为1
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
using namespace std;
typedef long long lt;
int read()
{
int f=1,x=0;
char ss=getchar();
while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();}
while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();}
return f*x;
}
const int maxn=2000010;
char ss[maxn];
int nxt[maxn];
void qnxt(char* a,int len)
{
int j=0; nxt[1]=0;
for(int i=2;i<=len;++i)
{
while(j>0&&ss[j+1]!=ss[i]) j=nxt[j];
if(ss[j+1]==ss[i]) j++;
nxt[i]=j;
}
}
int main()
{
while(scanf("%s",ss+1)!=EOF)
{
if(ss[1]=='.') break;
int len=strlen(ss+1);
qnxt(ss+1,len);
if(len%(len-nxt[len])!=0) printf("1\n");
else printf("%d\n",len/(len-nxt[len]));
}
return 0;
}