POJ1961:
First, use KMP "preprocessing" to get the pre (I am used to using the p array in the program ).
Then the key lies in the judgment that (I + 1) % (I-pre [I]) = 0 has a loop. How can this problem be solved? This is to divide the array str into (I + 1)/(I-pre [I]) parts. From the pre nature, we can see that all these parts are equal, that is, the minimum cyclic section, it is not clear that you can draw a few strokes on the number axis. This is the key to this question.
#include "stdio.h"int p[1000010],N;char str[1000010];void get_p(int n){ int i,j=-1; p[0]=-1; for(i=1;i<n;i++) { while(j>-1 && str[i]!=str[j+1]) j=p[j]; if(str[i] == str[j+1]) j++; p[i]=j; }}int main(){ int i,j,cas=1; while(scanf("%d",&N),N) { scanf("%s",str); get_p(N); printf("Test case #%d\n",cas++); for(i=1;i<N;i++) { if(p[i]!=-1 && (i+1)%(i-p[i])==0) printf("%d %d\n",i+1,(i+1)/(i-p[i])); } printf("\n"); }}
Poj2406
#include "stdio.h"#include "string.h"int ans;int p[1000010];char str[1000010];void get_p(int n){ int i,j=-1; p[0]=-1; for(i=1;i<n;i++) { while(j>-1 && str[i]!=str[j+1]) j=p[j]; if(str[i] == str[j+1]) j++; p[i]=j; }}int main(){ int i,j,k,N; while(1) { scanf("%s",str); N=strlen(str); if(N==1 && str[0]=='.') break; get_p(N); ans=1; if(N==1) printf("1\n"); else{ if(N%(N-1-p[N-1])==0) printf("%d\n",N/(N-1-p[N-1])); else printf("1\n"); } }}