SPOJ - REPEATS —— 后缀数组 重复次数最多的连续重复子串

题目链接:https://vjudge.net/problem/SPOJ-REPEATS

 

REPEATS - Repeats

no tags 

 

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

Input:
1
17
b
a
b
b
a
b
a
a
b
a
a
b
a
a
b
a
b

Output:
4
since a (4, 3)-repeat is found starting at the 5th character of the input string.

 

 

题意:

给出一个字符串,求该字符串的重复次数最多的连续重复子串,输出重复次数。

 

题解:

论文上面的题。

 

 

代码如下:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <vector>
  6 #include <cmath>
  7 #include <queue>
  8 #include <stack>
  9 #include <map>
 10 #include <string>
 11 #include <set>
 12 using namespace std;
 13 typedef long long LL;
 14 const int INF = 2e9;
 15 const LL LNF = 9e18;
 16 const int MOD = 1e9+7;
 17 const int MAXN = 5e4+100;
 18 
 19 bool cmp(int *r, int a, int b, int l)
 20 {
 21     return r[a]==r[b] && r[a+l]==r[b+l];
 22 }
 23 
 24 int r[MAXN], sa[MAXN], Rank[MAXN], height[MAXN];
 25 int t1[MAXN], t2[MAXN], c[MAXN];
 26 void DA(int str[], int sa[], int Rank[], int height[], int n, int m)
 27 {
 28     n++;
 29     int i, j, p, *x = t1, *y = t2;
 30     for(i = 0; i<m; i++) c[i] = 0;
 31     for(i = 0; i<n; i++) c[x[i] = str[i]]++;
 32     for(i = 1; i<m; i++) c[i] += c[i-1];
 33     for(i = n-1; i>=0; i--) sa[--c[x[i]]] = i;
 34     for(j = 1; j<=n; j <<= 1)
 35     {
 36         p = 0;
 37         for(i = n-j; i<n; i++) y[p++] = i;
 38         for(i = 0; i<n; i++) if(sa[i]>=j) y[p++] = sa[i]-j;
 39 
 40         for(i = 0; i<m; i++) c[i] = 0;
 41         for(i = 0; i<n; i++) c[x[y[i]]]++;
 42         for(i = 1; i<m; i++) c[i] += c[i-1];
 43         for(i = n-1; i>=0; i--) sa[--c[x[y[i]]]] = y[i];
 44 
 45         swap(x, y);
 46         p = 1; x[sa[0]] = 0;
 47         for(i = 1; i<n; i++)
 48             x[sa[i]] = cmp(y, sa[i-1], sa[i], j)?p-1:p++;
 49 
 50         if(p>=n) break;
 51         m = p;
 52     }
 53 
 54     int k = 0;
 55     n--;
 56     for(i = 0; i<=n; i++) Rank[sa[i]] = i;
 57     for(i = 0; i<n; i++)
 58     {
 59         if(k) k--;
 60         j = sa[Rank[i]-1];
 61         while(str[i+k]==str[j+k]) k++;
 62         height[Rank[i]] = k;
 63     }
 64 }
 65 
 66 int dp[MAXN][20], mm[MAXN];
 67 void initRMQ(int n, int b[])
 68 {
 69     mm[0] = -1;
 70     for(int i = 1; i<=n; i++)
 71         dp[i][0] = b[i], mm[i] = ((i&(i-1))==0)?mm[i-1]+1:mm[i-1];
 72     for(int j = 1; j<=mm[n]; j++)
 73     for(int i = 1; i+(1<<j)-1<=n; i++)
 74         dp[i][j] = min(dp[i][j-1], dp[i+(1<<(j-1))][j-1]);
 75 }
 76 
 77 int RMQ(int x, int y)
 78 {
 79     if(x>y) swap(x, y);
 80     x++;
 81     int k = mm[y-x+1];
 82     return min(dp[x][k], dp[y-(1<<k)+1][k]);
 83 }
 84 
 85 int main()
 86 {
 87     int T, n;
 88     scanf("%d", &T);
 89     while(T--)
 90     {
 91         scanf("%d", &n);
 92         for(int i = 0; i<n; i++)
 93         {
 94             char ch;
 95             getchar();
 96             scanf("%c", &ch);
 97             r[i] = ch-'a'+1;
 98         }
 99         r[n] = 0;
100         DA(r, sa, Rank, height, n, 3);
101         initRMQ(n, height);
102 
103         int times = 0, L, R;
104         for(int len = 1; len<=n; len++)
105         for(int pos = 0; pos+len<n; pos += len)
106         {
107             int LCP = RMQ(Rank[pos], Rank[pos+len]);
108             int supplement = len - LCP%len;
109             int k = pos - supplement;
110             if(k>=0 && LCP%len && RMQ(Rank[k],Rank[k+len])>=supplement)
111                 LCP += supplement;
112             times = max(times, LCP/len+1);
113         }
114         printf("%d\n", times);
115     }
116 }
View Code

 

posted on 2018-02-25 15:09  h_z_cong  阅读(485)  评论(0编辑  收藏  举报

导航