spoj687 后缀数组重复次数最多的连续重复子串
Posted sweatOtt
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spoj687 后缀数组重复次数最多的连续重复子串相关的知识,希望对你有一定的参考价值。
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 = 50010; 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 = 0; i < m; i++)wc[i] = 0; for(int i = 0; i < n; i++)wc[x[i] = r[i]] ++; for(int i = 0; i < m; i++)wc[i] += wc[i-1]; for(int i = n - 1; i >= 0; i--)sa[--wc[x[i]]] = i; for(int k = 1,p = 1; p < n; m = p,k <<= 1){ p = 0; for(int i = n - k; i < n; i++)y[p++] = i; for(int i = 0; i < n; i++)if(sa[i] >= k)y[p++] = sa[i] - k; for(int i = 0; i < m; i++)wc[i] = 0; for(int i = 0; i < n; i++)wc[x[y[i]]] ++; for(int i = 0; i < m; i++)wc[i] += wc[i-1]; for(int i = n - 1; i >= 0; i--)sa[--wc[x[y[i]]]] = y[i]; swap(x,y); p = 1; x[sa[0]] = 0; for(int i = 1; i < n; i++){ x[sa[i]] = (y[sa[i]] == y[sa[i-1]] && y[sa[i]+k] == y[sa[i-1]+k])?p-1:p++; } } } void calheight(int *r,int *sa,int n){ for(int i = 1; i <= n; i++)Rank[sa[i]] = i; int j,k = 0; for(int i = 0; i < n; height[Rank[i++]] = k){ for(k?k--:0,j = sa[Rank[i]-1]; r[i+k]==r[j+k]; k++); } } int dp[MAXN][20]; void RMQ(){ for(int i = 1; i <= n; i++){ dp[i][0] = height[i]; } for(int i = 1; i < 20; i++){ for(int j = 1; j + (1 << i) - 1 <= n; j++){ dp[j][i] = min(dp[j][i-1],dp[(j+(1<<(i-1)))][i-1]); } } } int getnum(int x,int y){ x = Rank[x]; y = Rank[y]; if(x > y)swap(x,y); x += 1; int k = (int)((log(y - x + 1) * 1.0) / log(2.0)); return min(dp[x][k],dp[y - (1<<k) + 1][k]); } void solve(){ int ans = 1; for(int i = 1; i < n; i++){ for(int j = 0; j + i < n; j += i){ int ret = getnum(j,j+i); int t = ret / i + 1;// behind r[i] can repeat t times int tp = j - (i - ret % i); if(tp >= 0 && (ret % i != 0) && 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 = 0; i < n; i++){ scanf("%c",&s[i]); r[i] = s[i]; getchar(); } r[n] = 0; da(r,sa,n+1,128); calheight(r,sa,n); RMQ(); solve(); } return 0; }
以上是关于spoj687 后缀数组重复次数最多的连续重复子串的主要内容,如果未能解决你的问题,请参考以下文章