Power Strings
Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 26316 | Accepted: 11019 |
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.
求字符串的最小循环周期:
•先给出结论:
如果
len%(len-next[len-1])==0,
则字
符串中必存在最小循环节,且循环次数即为
len/(len-next[len-1])
•证明:必要性:因为字符串中存在最小循环节(设长度为k),next[len-1]=len-k,所以len%(len-next[len-1])==0;
• 充分性:令k1=len-next[len-1],由于k1整除len,所以可以相应的把len划分为n片区域(n=len/(k1)),从小到大依次表示为
•t1,t2...tn;由next数组的定义可知,t1=t2,t2=t3,...t(n-1)=tn,且相应的片区域即为最小,所以循环次数也为len/(len-next[len-1]);
AC代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <cmath>
#include <string>
#include <algorithm>
using namespace std;
char s[1000005];
int next[1000005];
int main()
{
while(scanf("%s",s)!=EOF)
{
if(strcmp(s,".")==0)
break;
int len=strlen(s);
memset(next,0,sizeof(next));
for(int i=1;i<len;i++)
{
int temp=next[i-1];
while(temp&&s[temp]!=s[i])
temp=next[temp-1];
if(s[temp]==s[i])
next[i]=temp+1;
else
next[i]=0;
}
if(len%(len-next[len-1])==0)
printf("%d\n",len/(len-next[len-1]));
else
printf("1\n");
}
return 0;
}