#include<iostream> #include<cstring> using namespace std; #define M 1000001 int next[M],len,n; char s[M],t[M]; void getnext(){ int i=1,j=0; next[i]=0; for(i=2;i<=len;i++){ while(j>0 && s[j+1]!=s[i]) j=next[j]; if(s[j+1]==s[i]) j++; next[i]=j; } } int main(){ /*kmp 中的next[i],表示的是 s[1]=s[i-next[i]],s[2]=s[i-next[i]+1],……s[next[i]]=s[i]; 就是s[i] 前面的 i-next[i] 已经和s 前next[i]个匹配成功 通过一个一个匹配下来,可以得知,如果s已经匹配到next[i]而i-next[i]就是它这一部分的长度,并且前面也是按照此规律, 那么当i=0( mod (i-next[i]) ) 就表示有 i/(i-next[i])段在目前是完全相同的。 如: a b c a b c a b c a b d 它的next值:0 0 0 1 2 3 4 5 6 7 8 0 如果是叠加的必然是按递增上去的, 实际上是由 abcabc (3->9) 向前平移 3个单位得到abcabc(1->6) (其中3-9 和 1-6 指的是从s[3]->s[9] 以及 s[1]-s[6]) 因为 next函数本来就是主串自身的一种匹配。 */ while(cin>>len && len){ cin>>(s+1); getnext(); cout<<"Test case #"<<++n<<endl; for(int i=2;i<=len;i++){ if(! (i%(i-next[i]) )&& i/(i-next[i])>1 ) cout<<i<<" "<<i/(i-next[i])<<endl; } cout<<endl; } return 0; }