POJ3693 Maximum repetition substring suffix array

POJ - 3693 Maximum repetition substring

 

The meaning of problems

A string input, find the most frequently repeated continuously repeated string, if there is the same number of times, the minimum output sequence dictionaries

 

Sample input

ccabababc

daabbccaa

#

 

Sample Output

Case 1: BAB

Case 2: aa

 

  . 1 #include <the iostream>
   2 #include <cstdio>
   . 3 #include <CString>
   . 4 #include <algorithm>
   . 5  the using  namespace STD;
   . 6  const  int MAXN = 1E5 + . 5 ;
   . 7  char S [MAXN];
   . 8  int SA [MAXN] , T [MAXN], T2 [MAXN], C [MAXN];
   . 9  int n-;
 10  // suffix array configuration string s, each character must be a value-m. 1 ~ 0 
. 11  void build_sa ( int m) {
 12 is      int * X = T, Y * = T2;
 13 is      // radix sorting
 14     for(int i = 0; i < m; i++) c[i] = 0;
 15     for(int i = 0; i < n; i++) c[x[i] = s[i]]++;
 16     for(int i = 1; i < m; i++) c[i] += c[i-1];
 17     for(int i = n-1; i >= 0; i--) sa[--c[x[i]]] = i;
 18     for(int k = 1; k <= n; k <<= 1) {
 19         int p = 0 ;
 20          // second keyword directly sa sort the array 
21 is          for ( int I = NK; I <n-; I ++) Y [P ++] = I;
 22 is          for ( int I = 0 ; I <n-; I ++) IF (SA [I]> = K) Y [P ++] = SA [I] - K;
 23 is          // radix sort a first key 
24          for ( int I = 0 ; I <m; I ++) C [I] = 0 ;
 25          for ( int I = 0 ; I <n-; I ++) C [X [Y [I]]] ++ ;
 26 is          for ( int I = . 1; i < m; i++) c[i] += c[i-1];
 27         for(int i = n-1; i>= 0; i--) sa[--c[x[y[i]]]] = y[i];
 28         //根据sa和y数组计算新的x数组
 29         swap(x, y);
 30         p = 1;
 31         x[sa[0]] = 0;
 32         for(int i = 1; i < n; i++)
 33             x[sa[i]] = (y[sa[i-1]] == y[sa[i]] && y[sa[i-1]+k] == y[sa[i]+k] ? p-1: P ++ );
 34 is          IF (P> = n-) BREAK ;
 35          m = P;
 36      }
 37 [  }
 38 is  
39  int rank_ [MAXN]; // Rank [i] representative of suffix i is marked sa array 
40  int height [MAXN]; // height [I] is defined as sa [i-1] and sa [i] is the longest common prefix
 41 is  // the LCP length suffix j and k are equal RMQ (height, rank [j] +1, Rank [K]) 
42 is  void get_height () {
 43 is      int I, J, K = 0 ;
 44 is      for ( int I = 0; i < n; i++) rank_[sa[i]] = i;
 45     for(int i = 0; i < n; i++) {
 46         if(!rank_[i]) continue;
 47         int j = sa[rank_[i]-1];
 48         if(k) k--;
 49 
 50         while(s[i+k] == s[j+k]) k++;
 51         height[rank_[i]] = k;
 52     }
 53 }
 54 int d[maxn][50];
 55 void rmq_init() {
 56     for(int i = 0; i < n; i++) d[i][0] = height[i];
 57     for(int j = 1; (1<<j) <= n; j++)
 58         for(int i = 0; i + (1<<j) - 1 < n; i++)
 59             d[i][j] = min(d[i][j-1], d[i+(1<<(j-1))][j-1]);
 60 }
 61 int rmq(int l, int r) {
 62     if(l == r) return n-l;
 63     if(rank_[l] > rank_[r]) swap(l, r);
 64     int L = rank_[l]+1;
 65     int R = rank_[r];
 66     int k = 0;
 67     while((1<<(k+1)) <= R-L+1) k++;
 68     return min(d[L][k], d[R-(1<<k)+1][k]);
 69 }
 70 
 71 int a[maxn];
 72 int main() {
 73     int kase = 0;
 74     while(~scanf("%s", s) && s[0] != '#') {
 75         int L = strlen(s);
 76         n = L + 1;
 77         build_sa(128);
 78         get_height();
 79         rmq_init();
 80         int mx = 0;
 81         int cnt = 0;
 82         //Find the most repeated number of successive substrings single sub-string length, there may be several repetitions of the same sub-string 
83          for ( int L = . 1 ; L <= L; L ++ ) {
 84              for ( int J = 0 ; J + L <L; = J + L) {
 85                  int K = RMQ (J, J + L); // LCP 
86                  int RES = K / L + . 1 ;
 87                  int POS = J - (L - (K% L) );
 88                  IF (POS> = 0 && && RMQ L% K (POS, POS + L)) RES ++ ;
 89                  IF (RES> MX) {
 90                      MX =RES;
 91 is                      CNT = 0 ;
 92                      A [CNT ++] = L;
 93                  } the else  IF (RES == MX) {
 94                      A [CNT ++] = L;
 95                  }
 96              }
 97          }
 98          // find the lexicographically smallest 
99          int len = 0 , ST;
 100          for ( int I = . 1 ; I <&& n-len;! I ++ ) {
 101              for ( int j = 0; j < cnt; j++) {
102                 if(rmq(sa[i], sa[i] + a[j]) >= (mx - 1) * a[j]) {
103                     len = a[j];
104                     st = sa[i];
105                     break;
106                 }
107             }
108         }
109         printf("Case %d: ", ++kase);
110         for(int i = st; i < st + len * mx; i++) {
111             printf("%c", s[i]);
112         }
113         printf("\n");
114     }
115     return 0;
116 }

 

Guess you like

Origin www.cnblogs.com/wstong/p/11731712.html