Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 10612 | Accepted: 3277 |
Descriptionios
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.spa
Given a string containing lowercase letters, you are to find a substring of it with maximum repetition number.code
Inputblog
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.ip
The last test case is followed by a line containing a '#'.字符串
Outputget
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.input
Sample Inputstring
ccabababc daabbccaa #
Sample Outputit
Case 1: ababab Case 2: aa
Source
//論文題,仍是挺難的。連續出現1次是確定的,咱們枚舉重複部分的長度L,把而後把字符串分紅長爲L的若干段,s[0],s[L],s[2*L]... //那麼要求的子串必然會包含相鄰的兩段,因此看s[i*L]和s[i*L+L]向前和向後能匹配多遠(i*L~i*L+L是其中的一部分),即求出來他們 //的lcp,向後最遠最可能是lcp的終點,向前咱們能夠給他向前枚舉L長度個單位(不必枚舉超過L,前一段計算包含了)看看最多能匹 //配多少,還要保持字典序最小。 #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int MAXN=200000; int sa[MAXN+9],he[MAXN+9],ra[MAXN+9],xx[MAXN+9],yy[MAXN+9],buc[MAXN+9],f[MAXN+9][30]; char s[MAXN+9]; int len,m; void get_suf() { int *x=xx,*y=yy; for(int i=0;i<m;i++) buc[i]=0; for(int i=0;i<len;i++) buc[x[i]=s[i]]++; for(int i=1;i<m;i++) buc[i]+=buc[i-1]; for(int i=len-1;i>=0;i--) sa[--buc[x[i]]]=i; for(int k=1;k<=len;k<<=1){ int p=0; for(int i=len-1;i>=len-k;i--) y[p++]=i; for(int i=0;i<len;i++) if(sa[i]>=k) y[p++]=sa[i]-k; for(int i=0;i<m;i++) buc[i]=0; for(int i=0;i<len;i++) buc[x[y[i]]]++; for(int i=1;i<m;i++) buc[i]+=buc[i-1]; for(int i=len-1;i>=0;i--) sa[--buc[x[y[i]]]]=y[i]; swap(x,y); p=1;x[sa[0]]=0; for(int i=1;i<len;i++){ if(y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]) x[sa[i]]=p-1; else x[sa[i]]=p++; } if(p>=len) break; m=p; } for(int i=0;i<len;i++) ra[sa[i]]=i; int k=0; for(int i=0;i<len;i++){ if(ra[i]==0) { he[0]=0; continue; } if(k) k--; int j=sa[ra[i]-1]; while(s[i+k]==s[j+k]&&i+k<len&&j+k<len) k++; he[ra[i]]=k; } } void rmq1() { he[0]=he[len]=0; for(int i=0;i<=len;i++) f[i][0]=he[i]; for(int j=1;(1<<j)<=len;j++){ for(int i=0;i+(1<<j)-1<=len;i++) f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]); } } int rmq2(int ql,int qr) { if(ql>qr) swap(ql,qr); ql++; int k=0; while(1<<(k+1)<=qr-ql+1) k++; return min(f[ql][k],f[qr-(1<<k)+1][k]); } void solve(int &st,int &ed,int ans) { for(int l=1;l*2<=len;l++){ for(int i=0;i+l<len;i+=l){ if(s[i]!=s[i+l]) continue; int ll=rmq2(ra[i],ra[i+l]); for(int j=0;j<=l;j++){ int ii=i-j; if(ii<0||s[ii]!=s[ii+l]) break; int num=(j+ll)/l+1; if(num>ans||(num==ans&&ra[st]>ra[ii])){ ans=num; st=ii;ed=st+ans*l-1; } } } } } int main() { int cas=0; while(scanf("%s",s)&&s[0]!='#'){ len=strlen(s); m=200; get_suf(); rmq1(); int st=sa[0],ed=sa[0]; solve(st,ed,1); printf("Case %d: ",++cas); for(int i=st;i<=ed;i++) printf("%c",s[i]); printf("\n"); } return 0; }