REPEATS - Repeats
A string s is called an (k,l)-repeat if s is obtained by concatenating k>=1 times some seed string t with length l>=1. For example, the string
s = abaabaabaaba
is a (4,3)-repeat with t = aba as its seed string. That is, the seed string t is 3 characters long, and the whole string s is obtained by repeating t 4 times.
Write a program for the following task: Your program is given a long string u consisting of characters ‘a’ and/or ‘b’ as input. Your program must find some (k,l)-repeat that occurs as substring within u with k as large as possible. For example, the input string
u = babbabaabaabaabab
contains the underlined (4,3)-repeat s starting at position 5. Since u contains no other contiguous substring with more than 4 repeats, your program must output the maximum k.
Input
In the first line of the input contains H- the number of test cases (H <= 20). H test cases follow. First line of each test cases is n - length of the input string (n <= 50000), The next n lines contain the input string, one character (either ‘a’ or ‘b’) per line, in order.
Output
For each test cases, you should write exactly one interger k in a line - the repeat count that is maximized.
Example
1
17
b
a
b
b
a
b
a
a
b
a
a
b
a
a
b
a
b
Output:
4
/*
* Author: sweat123
* Created Time: 2016/6/29 15:28:42
* File Name: main.cpp
*/
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<string>
#include<vector>
#include<cstdio>
#include<time.h>
#include<cstring>
#include<iostream>
#include<algorithm>
#define INF 1<<30
#define MOD 1000000007
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define pi acos(-1.0)
using namespace std;
const int MAXN = ;
int wa[MAXN],wb[MAXN],wc[MAXN],n,height[MAXN],Rank[MAXN],r[MAXN],sa[MAXN];
char s[MAXN];
void da(int *r,int *sa,int n,int m){
int *x = wa,*y = wb;
for(int i = ; i < m; i++)wc[i] = ;
for(int i = ; i < n; i++)wc[x[i] = r[i]] ++;
for(int i = ; i < m; i++)wc[i] += wc[i-];
for(int i = n - ; i >= ; i--)sa[--wc[x[i]]] = i;
for(int k = ,p = ; p < n; m = p,k <<= ){
p = ;
for(int i = n - k; i < n; i++)y[p++] = i;
for(int i = ; i < n; i++)if(sa[i] >= k)y[p++] = sa[i] - k;
for(int i = ; i < m; i++)wc[i] = ;
for(int i = ; i < n; i++)wc[x[y[i]]] ++;
for(int i = ; i < m; i++)wc[i] += wc[i-];
for(int i = n - ; i >= ; i--)sa[--wc[x[y[i]]]] = y[i];
swap(x,y);
p = ;
x[sa[]] = ;
for(int i = ; i < n; i++){
x[sa[i]] = (y[sa[i]] == y[sa[i-]] && y[sa[i]+k] == y[sa[i-]+k])?p-:p++;
}
}
}
void calheight(int *r,int *sa,int n){
for(int i = ; i <= n; i++)Rank[sa[i]] = i;
int j,k = ;
for(int i = ; i < n; height[Rank[i++]] = k){
for(k?k--:,j = sa[Rank[i]-]; r[i+k]==r[j+k]; k++);
}
}
int dp[MAXN][];
void RMQ(){
for(int i = ; i <= n; i++){
dp[i][] = height[i];
}
for(int i = ; i < ; i++){
for(int j = ; j + ( << i) - <= n; j++){
dp[j][i] = min(dp[j][i-],dp[(j+(<<(i-)))][i-]);
}
}
}
int getnum(int x,int y){
x = Rank[x];
y = Rank[y];
if(x > y)swap(x,y);
x += ;
int k = (int)((log(y - x + ) * 1.0) / log(2.0));
return min(dp[x][k],dp[y - (<<k) + ][k]);
}
void solve(){
int ans = ;
for(int i = ; i < n; i++){
for(int j = ; j + i < n; j += i){
int ret = getnum(j,j+i);
int t = ret / i + ;// behind r[i] can repeat t times
int tp = j - (i - ret % i);
if(tp >= && (ret % i != ) && getnum(tp,tp+i) >= ret){
t ++;
}
ans = max(t,ans);
}
}
printf("%d\n",ans);
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
getchar();
for(int i = ; i < n; i++){
scanf("%c",&s[i]);
r[i] = s[i];
getchar();
}
r[n] = ;
da(r,sa,n+,);
calheight(r,sa,n);
RMQ();
solve();
}
return ;
}