The repetition number of a string is defined as the maximum number R such that the string can be partitioned into R same consecutive substrings. For example, the repetition number of "ababab" is 3 and "ababa" is 1.
Given a string containing lowercase letters, you are to find a substring of it with maximum repetition number.
Input
The input consists of multiple test cases. Each test case contains exactly one line, which
gives a non-empty string consisting of lowercase letters. The length of the string will not be greater than 100,000.
The last test case is followed by a line containing a '#'.
Output
For each test case, print a line containing the test case number( beginning with 1) followed by the substring of maximum repetition number. If there are multiple substrings of maximum repetition number, print the lexicographically smallest one.
Sample Input
ccabababc daabbccaa #
Sample Output
Case 1: ababab Case 2: aa
题意:给定一个字符串,求出其子串中,重复次数最多的串,如果有相同的,输出字典序最小的
思路:枚举长度l,把字符串按l分段,这样对于长度为l的字符串,肯定会包含一个分段位置,这样一来就可以在每个分段位置,往后做一次lcp,求出最大匹配长度,然后如果匹配长度有剩余,看剩余多少,就往前多少位置再做一次lcp,如果匹配出来长度更长,匹配次数就加1,这样就可以枚举过程中保存下答案了
这样问题还有字典序的问题,这个完全可以利用sa数组的特性,从字典序最小往大枚举,直到出现一个符合的位置就输出结束
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<cstring> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstdio> 6 using namespace std; 7 int const N=200000+3; 8 int wa[N<<1],wb[N<<1],rk[N],h[N],sa[N],num[N],wv[N],lg[N<<1],f[N<<1][17]; 9 char s[N<<1]; 10 int cmp(int *r,int x,int y,int z){ 11 return r[x]==r[y] && r[x+z]==r[y+z]; 12 } 13 void build_sa(char *r,int *sa,int n,int m){ 14 int i,j,p,*x=wa,*y=wb; 15 for(i=0;i<m;i++) num[i]=0; 16 for(i=0;i<n;i++) num[x[i]=r[i]]++; 17 for(i=1;i<m;i++) num[i]+=num[i-1]; 18 for(i=n-1;i>=0;i--) sa[--num[x[i]]]=i; 19 for(p=1,j=1;p<n;j<<=1,m=p){ 20 for(p=0,i=n-j;i<n;i++) y[p++]=i; 21 for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; 22 for(i=0;i<m;i++) num[i]=0; 23 for(i=0;i<n;i++) wv[i]=x[y[i]]; 24 for(i=0;i<n;i++) num[wv[i]]++; 25 for(i=1;i<m;i++) num[i]+=num[i-1]; 26 for(i=n-1;i>=0;i--) sa[--num[wv[i]]]=y[i]; 27 swap(x,y); 28 for(i=1,p=1,x[sa[0]]=0;i<n;i++) 29 x[sa[i]]=cmp(y,sa[i],sa[i-1],j)? p-1:p++; 30 } 31 for(i=0;i<n;i++) rk[i]=x[i]; 32 } 33 void build_h(char *r,int *sa,int n){ 34 int k=0; 35 for(int i=1;i<=n;i++){ 36 if(k) k--; 37 int j=sa[rk[i]-1]; 38 while ( r[i+k]==r[j+k]) k++; 39 h[rk[i]]=k; 40 } 41 } 42 void build_rmq(int n){ 43 for(int i=1;i<=n;i++) f[i][0]=h[i]; 44 for(int j=1;j<=16;j++) 45 for(int i=1;i<=n;i++) f[i][j]=min(f[i][j-1],f[i+(1<<j-1)][j-1]); 46 } 47 int query(int x,int y){ 48 if(x>y) swap(x,y); 49 x++; 50 int k=lg[y-x+1]; 51 return min(f[x][k],f[y-(1<<k)+1][k]); 52 } 53 int main(){ 54 int cas=0; 55 for(int i=0;i<=16;i++) 56 for(int j=(1<<i);j<(1<<i+1);j++) 57 lg[j]=i; 58 while (scanf("%s",s)!=EOF){ 59 if(strcmp(s,"#")==0) break; 60 int len=strlen(s); 61 build_sa(s,sa,len+1,130); 62 build_h(s,sa,len); 63 build_rmq(len); 64 int ans=0,l=0,r=0; 65 for(int L=1;2*L<=len;L++) 66 for(int i=0;(i+1)*L<len;i++){ 67 int x=L*i,y=L*(i+1); 68 if(s[x]!=s[y]) continue; 69 int z=query(rk[x],rk[y]); 70 int t1=y+z-1; 71 int t0=0; 72 for(int j=0;j<L;j++){ 73 if(x-j<0 || s[x-j]!=s[y-j]) break; 74 t0=x-j; 75 int now=(t1-t0+1)/L; 76 if(now>ans || (now==ans && rk[t0]<rk[l])) 77 ans=now,l=t0,r=t0+now*L-1; 78 } 79 } 80 printf("Case %d: ",++cas); 81 if(ans==0) printf("%c\n",s[sa[1]]); 82 else { 83 for(int i=l;i<=r;i++) printf("%c",s[i]); 84 printf("\n"); 85 } 86 } 87 return 0; 88 }