http://poj.org/problem?id=3693
Maximum Repetition substring
Time Limit: 1000MS |
|
Memory Limit: 65536K |
Total Submissions: 7241 |
|
Accepted: 2162 |
Description
The repetition number of a string is defined as the maximum number R Such so 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 is 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 is not being greater than 100,000.
The last test was 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 R Epetition number. If There is multiple substrings of maximum repetition number, print the lexicographically smallest one.
Sample Input
ccabababcdaabbccaa#
Sample Output
Case 1:abababcase 2:aa
Source
Asia Hefei Regional Contest Online by USTC
Test instructions: The substring with the highest number of iterations within the string. The output dictionary order is minimal.
Idea: The classic question on the paper.
is to enumerate the length of L, to indicate that the length of the substring loop of L, must appear at least once, the occurrence of more than two times the enumeration must have s[i]==s[i+l], and then the two I and i+l suffix of the longest common prefix, recorded as K, then at least k/l+1, then is s[i] Make up enough to see if you can match one more. This gives the maximum number of cycles for substrings of length L.
For the smallest dictionary order, we enumerate the SA array and determine if the longest public prefix of the sa[i],sa[i+l] suffix is satisfied, and the first satisfaction is the smallest dictionary order.
/** * @author neko01 *///#pragma comment (linker, "/stack:102400000,102400000") #include <cstdio> #include < cstring> #include <string.h> #include <iostream> #include <algorithm> #include <queue># Include <vector> #include <cmath> #include <set> #include <map>using namespace Std;typedef long Long LL; #define MIN3 (a,b,c) min (a,min (b,c)) #define MAX3 (A,B,C) max (A,max (b,c)) #define PB Push_back#define MP (A, b) make_ Pair (A, B) #define CLR (a) memset (a,0,sizeof a) #define CLR1 (a) memset (a,-1,sizeof a) #define DBG (a) printf ("%d\n", a) typedef pair<int,int> PP;CONST Double Eps=1e-9;const double Pi=acos ( -1.0); const int N=100005;int sa[n]; The number of the row is which suffix//sa[1~n] is a valid value, Sa[0] must be n is an invalid value int rank[n]; Rank suffix i row//rank[0~n-1] is valid value, Rank[n] must be 0 invalid value int height[n]; Sa[i] and Sa[i-1] The longest common prefix//height[2~n] is a valid value int t1[n],t2[n],c[n];int dp[n][20]; RMP array void Build_sa (int s[],int n,int m) {int *x=t1,*y=t2; First round count sort for (int i=0;i<m;i++) c[i]=0; for (int i=0;i<n; i++) c[x[i]=s[i]]++; for (int i=1;i<m;i++) c[i]+=c[i-1]; for (int i=n-1;i>=0;i--) sa[--c[x[i]]]=i; for (int j=1;j<=n;j<<=1) {int p=0; Use the SA array directly to sort the second keyword for (int i=n-j;i<n;i++) y[p++]=i; for (int i=0;i<n;i++) if (sa[i]>=j) y[p++]=sa[i]-j; Count sort first keyword for (int i=0;i<m;i++) c[i]=0; for (int i=0;i<n;i++) c[x[y[i]]]++; for (int i=1;i<m;i++) c[i]+=c[i-1]; for (int i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i]; Calculates a new x array of swaps based on the SA and X arrays; p=1,x[sa[0]]=0; for (int i=1;i<n;i++) x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+j]==y[sa[i]+j]?p-1:p++; if (p>=n) break; M=p; }}void getheight (int s[],int n) {int k=0; for (int i=0;i<=n;i++) rank[sa[i]]=i; for (int i=0;i<n;i++) {if (k) k--; int j=sa[rank[i]-1]; while (S[i+k]==s[j+k]) k++; Height[rank[i]]=k; }}void initrmq (int n) {foR (int i=1;i<=n;i++) dp[i][0]=height[i]; for (int j=1, (1<<j) <=n;j++) for (int i=1;i+ (1<<J) -1<=n;i++) dp[i][j]=min (dp[i][j-1],dp[i + (1<< (j-1))][j-1]);} int LCP (int l,int r) {int k=0; L=RANK[L]; R=RANK[R]; if (l>r) swap (L,R); l++; while ((1<< (k+1)) <=r-l+1) k++; return min (dp[l][k],dp[r-(1<<k) +1][k]);} Char S[n];int a[n]; The array length to be sorted is N, put in 0~n-1, and a 0int res[n];int main () {int cnt=0 in the last face; while (~SCANF ("%s", s)) {if (strcmp (S, ' # ') ==0) break; int N=strlen (s); for (int i=0;i<n;i++) a[i]=s[i]-' a ' +1; a[n]=0; Build_sa (a,n+1,28); GetHeight (A,n); INITRMQ (n); int ans=0,tot=0; Ans is a maximum number of occurrences for (int l=1;l<=n/2;l++)//Enumeration L length substring can match {for (int i=0;i+l<n;i+=l) {if (s[i]!=s[i+l]) continue; int K=LCP (I,I+L); int t=k/l+1; int r=i-(L-K%L); //printf ("%d%d%d%d\n", i,i+l,k,k/l+1); if (R>=0&&LCP (r,r+l) >=k)//See if you can still match a t++; if (T>ans) {ans=t; tot=0; Res[tot++]=l; } else if (ans==t) res[tot++]=l; }} int len=0,ss; for (int i=1;i<=n&&!len;i++)//Enumerate SA array to find the smallest dictionary order {for (int j=0;j<tot;j++) { int L=RES[J]; if (LCP (sa[i],sa[i]+l) >= (ans-1) *l) {len=l; Ss=sa[i]; Break }}} s[ss+len*ans]= ' + '; printf ("Case%d:%s\n", ++CNT,S+SS); } return 0;}
poj3693 Maximum repetition substring suffix array