UVALIVE 3026 Period
题意:给你一个字符串,问第i位前是否有循环节,若存在,则循环节是多少?
思路:考察失配函数f[i]的意义。只要i%(i-f[i])==0,则循环节长度为i/(i-f[i])。字符在[0,f[i]],[i-f[i],i]范围内的相等,所以如果存在循环节则每i-f[i]可以分为一段。理解起来比较抽象,模拟一遍。
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <cstdlib> 5 #include <iostream> 6 #include <algorithm> 7 #include <queue> 8 #include <map> 9 #include <vector> 10 #include <time.h> 11 #define clc(a,b) memset(a,b,sizeof(a)) 12 using namespace std; 13 const int maxn = 1000010; 14 const int inf=0x3f3f3f3f; 15 typedef long long LL; 16 char P[maxn]; 17 int f[maxn]; 18 19 int main() 20 { 21 int n,cas=0; 22 while(~scanf("%d",&n),n) 23 { 24 scanf("%s",P); 25 f[0]=0,f[1]=0; 26 for(int i=1;i<n;i++) 27 { 28 int j=f[i]; 29 while(j&&P[i]!=P[j]) 30 j=f[j]; 31 f[i+1]=(P[i]==P[j]?j+1:0); 32 } 33 printf("Test case #%d\n",++cas); 34 for(int i=2;i<=n;i++) 35 { 36 if(f[i]&&i%(i-f[i])==0) 37 printf("%d %d\n",i,i/(i-f[i])); 38 } 39 printf("\n"); 40 } 41 return 0; 42 }