POJ 2406 Power Strings(KMP)
题意
求最小循环节出现次数。
题解
循环节可以用KMP求。
有一个结论是如果(len%(len-nxt[len])==0)那么最小循环节长度为len-nxt[len]
那么最小的循环节出现次数就是len/(len-nxt[len])
那我们怎么证明呢
(黑色的方框代表nxt数组最长相等的前缀和后缀的字符串,然后用圆圈表示的字符串有一系列的相等关系,用箭头表示,又因为len%(len-nxt[len])所以一定恰好填满。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 const int N=1000100; 8 char s[N]; 9 int nxt[N]; 10 int main(){ 11 while(scanf("%s",s+1)){ 12 if(s[1]=='.')break; 13 int len=strlen(s+1); 14 nxt[0]=-1;nxt[1]=0; 15 for(int i=2,j=0;i<=len;i++){ 16 while(j&&s[j+1]!=s[i])j=nxt[j]; 17 if(s[j+1]==s[i])j++; 18 nxt[i]=j; 19 } 20 int ans=1; 21 if(len%(len-nxt[len])==0)ans=len/(len-nxt[len]); 22 printf("%d\n",ans); 23 } 24 return 0; 25 }