Input
The input consists of several test cases. Each test case consists of two lines. The first one contains N (2 <= N <= 1 000 000) – the size of the string S.The second line contains the string S. The input file ends with a line, having thenumber zero on it.
Output
For each test case, output "Test case #" and the consecutive test case number on a single line; then, for each prefix with length i that has a period K > 1, output the prefix size i and the period K separated by a single space; the prefix sizes must be in increasing order. Print a blank line after each test case.Sample Input
3 aaa 12 aabaabaabaab 0
Sample Output
Test case #1 2 2 3 3 Test case #2 2 2 6 2 9 3 12 4
题解:如果一个长度为n的字符串(假设从0开始),n%(n-nxt[n-1])==0 ,那么n-nxt[n-1]就是这个字符串的最小循环长度,n/(n-nxt[n-1])为其最大循环周期,如果不等于0,设x=n%(n-nxt[n-1]) 那么该字符串加上x个字符后使得n-nxt[n-1] 为其最小循环长度
例题:http://acm.hdu.edu.cn/showproblem.php?pid=3746;
#include<cstdio> #include<string> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N=1e6+5; typedef long long ll; ll nxt[N]; struct stu{ ll a,b; bool friend operator <(const stu &x,const stu &y){ if(x.a!=y.a) return x.a<y.a; } }arr[N]; int main(){ int t,k=0; while(~scanf("%d",&t)!=EOF,t){ memset(nxt,0,sizeof(nxt)); k++; string a; cin>>a; for(int i=1;i<a.size();i++){ int j=nxt[i-1]; while(j>0&&a[i]!=a[j]) j=nxt[j-1]; if(a[i]==a[j]) j++; nxt[i]=j; } ll pos=0; printf("Test case #%d\n",k); for(int i=1;i<a.size();i++) { int j=i+1;//总长度, // j%(j-nxt[i])用来判断j-nxt[i]是否可以作为该段的最小循环长度, // j/(j-nxt[i]) 循环周期 if(j%(j-nxt[i])==0 && j/(j-nxt[i])>=2){ arr[pos].a=j; arr[pos++].b=j/(j-nxt[i]); } } sort(arr,arr+pos); for(int i=0;i<pos;i++){ cout<<arr[i].a<<" "<<arr[i].b<<endl; } cout<<endl; } return 0; }