后缀数组题目整理

最近在跟着 罗穗骞 的论文学习后缀数组, 不亏是神牛的论文。无论是算法讲解,还是习题举例都非常不错。下面把最进做的几道后缀数组整理一下。

1.两字符串的最长公共子串

 

 1 #include <stdio.h>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <sstream>
 5 #include <stdlib.h>
 6 #include <string.h>
 7 #include <limits.h>
 8 #include <vector>
 9 #include <string>
10 #include <time.h>
11 #include <math.h>
12 #include <queue>
13 #include <stack>
14 #include <set>
15 #include <map>
16 #define INF 0x3f3f3f3f
17 #define Zero(x)  memset((x),0, sizeof(x))
18 #define Neg(x) memset((x), -1, sizeof(x))
19 #define dg(x) cout << #x << " = " << x << endl
20 #define pk(x)   push_back(x)
21 #define pok()   pop_back()
22 #define eps 1e-8
23 #define pii pair<int, int>
24 #define pi acos(-1.0)
25 using namespace std;
26 typedef long long ll;
27 bool debug = true;
28 int OK = 1;
29 const int maxn = 220000;
30 int sa[maxn], r[maxn], height[maxn], t1[maxn], t2[maxn], c[maxn];
31 int rk[maxn];
32 char str[maxn];
33 bool cmp(int *r, int a,int b, int l){
34     return r[a] == r[b] && r[a + l] == r[b + l];
35 }
36 
37 void da(int str[], int sa[], int rk[], int height[], int n, int m){
38     n++;
39     int i, j, p, *x = t1, *y = t2;
40     for(i = 0; i < m; i++) c[i] = 0;
41     for(i = 0; i < n; ++i) c[x[i] = str[i]]++;
42     for(i = 1; i < m; ++i) c[i] += c[i - 1];
43     for(i = n - 1; i >= 0; --i) sa[--c[x[i]]] = i;
44     for(j = 1; j <= n; j <<= 1){
45         p = 0;
46         for(i = n - j; i < n; ++i) y[p++] = i;
47         for(i = 0; i < n; ++i) if(sa[i] >= j) y[p++] = sa[i] - j;
48         for(i = 0; i < m; ++i) c[i] = 0;
49         for(i = 0; i < n; ++i) c[x[y[i]]]++;
50         for(i = 1; i  < m; ++i) c[i] += c[i - 1];
51         for(i = n - 1; i >= 0; --i) sa[--c[x[y[i]]]] = y[i];
52         swap(x, y);
53         p = 1; x[sa[0]] = 0;
54         for(i = 1; i < n; ++i)
55             x[sa[i]] = cmp(y, sa[i - 1], sa[i], j)? p - 1: p++;
56         if(p >= n) break;
57         m = p;
58     }
59     int k = 0;
60     n--;
61     for(i = 0; i <= n; ++i) rk[sa[i]] = i;
62     for(i = 0; i <n ; ++i){
63         if(k) k--;
64         j = sa[rk[i] - 1];
65         while(str[i + k] == str[j + k]) ++k;
66         height[rk[i]] = k;
67     }
68 }
69 int main(){
70     //freopen("data.in","r",stdin);
71     //freopen("data.out","w",stdout);
72     //cin.sync_with_stdio(false);
73     while(scanf("%s", str) != EOF){
74         int len = strlen(str);
75         int len1 = len;
76         str[len] = '9';
77         scanf("%s", str + len + 1);
78         len = strlen(str);
79         for(int i = 0; i < len; ++i) r[i] = str[i];
80         r[len] = 0;
81         da(r, sa, rk, height, len, 128);
82         int mx = 0;
83         for(int i = 2; i < len; ++i){
84             if(mx < height[i] && (sa[i] > len1 && sa[i - 1] < len1 || sa[i] < len1 && sa[i - 1] > len1)){
85                 mx = height[i];
86             }
87         }
88         cout << mx << endl;
89     }
90     return 0;
91 }
View Code

 

2.不可重叠最长重复子串poj 1743( 二分长度k, height数组划分)

/********Good Luck*********
*
*Author: yeahpeng
*
*Time: 2015-10-05-22.33
*
**************************/
//#pragma comment(linker, "/STACK:102400000,102400000")
#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>


#ifdef DEBUG_yp
#define dg(x) cout << #x << " = " << x << endl
#define dg2(x1, x2) cout << #x1 << " = " << x1 << ", " << #x2 << " = " << x2 << endl
#define dg3(x1, x2, x3) cout << #x1 << " = " << x1 << ", " << #x2 << " = " << x2 << ", " << #x3 << " = " << x3 << endl
#define dgarr(arr, n) arrout(arr, n);
#else
#define dg(x) ;
#define dg2(x1, x2) ;
#define dg3(x1, x2, x3) ;
#define dgarr(arr, n) ;
#endif
#define Rep(i, v) for(int i = 0; i < int(v); ++i)
#define Rep1(i, v) for(int i = 1; i <= int(v); ++i)
#define Repe(i, l, r) for(int i = int(l); i < int(r); ++i)
#define Zero(x)  memset((x),0, sizeof(x))
#define Neg(x) memset((x), -1, sizeof(x))
#define PK(x)   push_back(x)
#define PPK()   pop_back()
#define PII pair<int, int>
#define MP(x, y) make_pair((x), (y))
#define F  first
#define S  second
using namespace std;
typedef long long ll;
void arrout(int arr[], int len){
    for(int i = 0; i <= len; ++i)
        cout << arr[i] << " ";
    cout << endl;
}
int OK = 1;
const int INF = 0x3f3f3f3f;
const int maxn = 22000;
int t1[maxn], t2[maxn], c[maxn];
int rk[maxn], sa[maxn], height[maxn];

bool cmp(int *r, int a, int b, int l){
    return r[a] == r[b] && r[a + l] == r[b + l];
}
void da(int str[], int sa[], int rk[], int height[], int n, int m){
    n++;
    int i, j, p, *x = t1, *y = t2;
    for (i = 0; i < m; ++i) c[i] = 0;
    for (i = 0; i < n; ++i) c[x[i] = str[i]]++;
    for (i = 1; i < m; ++i) c[i] += c[i - 1];
    for (i = n - 1; i >= 0; --i) sa[--c[x[i]]] = i;
    for (j = 1; j <= n; j <<= 1){
        p = 0;
        for (i = n - j; i < n; ++i) y[p++] = i;
        for (i = 0; i < n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j;
        for (i = 0; i < m; ++i) c[i] = 0;
        for (i = 0; i < n; ++i) c[x[y[i]]]++;
        for (i = 1; i < m; ++i) c[i] += c[i - 1];
        for (i = n - 1; i >= 0; --i) sa[--c[x[y[i]]]] = y[i];
        swap(x, y);
        p = 1; x[sa[0]] = 0;
        for (i = 1; i < n; ++i) x[sa[i]] = cmp(y, sa[i - 1], sa[i], j) ? p - 1 : p++;
        m = p;
    }
    int k = 0;
    n--;
    for (i = 0; i <= n; ++i) rk[sa[i]] = i;
    for(i = 0; i < n; ++i){
        if(k)k--;
        j = sa[rk[i]-1];
        while(str[i+k] == str[j+k]) k++;
        height[rk[i]] = k;
    }
}
int n;
int arr[maxn], r[maxn];
bool check(int mid){
    int mn = INF, mx = 0;
    for(int i = 2; i <= n; ++i){
        if(height[i] >= mid){
            mn = INF;
            mx = 0;
            while(i<= n && height[i] >= mid){
                mn = min(mn, sa[i-1]);
                mn = min(mn, sa[i]);
                mx = max(mx, sa[i]);
                mx = max(mx, sa[i-1]);
                i++;
            }
            if(mx - mn > mid) return true;
        }
    }
    return false;
}
int main(){
#ifdef DEBUG_yp
    //freopen("data.out", "w", stdout);
    //freopen("data.in", "r", stdin);
#endif
    //cin.sync_with_stdio(false);cin.tie(0);
    while(scanf("%d", &n), n){
        for(int i = 0; i < n; ++i) scanf("%d", arr + i);
        for(int i = 0; i < n-1; ++i) r[i] =  arr[i+1] - arr[i] + 100;
        n--;
        r[n] = 0;
        da(r, sa, rk, height, n, 200);
        int ans = 0;
        dgarr(height, n);
        dgarr(sa, n);
        dgarr(r, n);
        dgarr(rk, n);
        int l = 0, rr = n, m;
        while(l <= rr){
            m = (l + rr) >> 1;
            dg3(m, l, rr);
            if(check(m)) l = m + 1;
            else rr = m - 1;
        }
        ans = l-1;
        if(ans >= 4)
            cout << ans + 1 << endl;
        else puts("0");
    }
    return 0;
}
View Code

 

 

3.可重叠的最少重复k次的最长重复子串

 

  1 /*
  2  ***********Good LUCK**********
  3  * Author:  yeahpeng
  4  * Created Time:  2015/4/24 21:44:34
  5  * File Name: poj3693.cpp
  6  */
  7 #include <stdio.h>
  8 #include <iostream>
  9 #include <algorithm>
 10 #include <sstream>
 11 #include <stdlib.h>
 12 #include <string.h>
 13 #include <limits.h>
 14 #include <vector>
 15 #include <string>
 16 #include <time.h>
 17 #include <math.h>
 18 #include <queue>
 19 #include <stack>
 20 #include <set>
 21 #include <map>
 22 #define INF 0x3f3f3f3f
 23 #define Zero(x)  memset((x),0, sizeof(x))
 24 #define Neg(x) memset((x), -1, sizeof(x))
 25 #define dg(x) cout << #x << " = " << x << endl
 26 #define pk(x)   push_back(x)
 27 #define pok()   pop_back()
 28 #define eps 1e-8
 29 #define pii pair<int, int>
 30 #define pi acos(-1.0)
 31 using namespace std;
 32 typedef long long ll;
 33 bool debug = false;
 34 int OK = 1;
 35 const int maxn = 100100;
 36 char s[maxn];
 37 int t1[maxn], t2[maxn], c[maxn];
 38 bool cmp(int *r, int a,int b, int l){
 39     return r[a] == r[b] && r[a + l] == r[b + l];
 40 }
 41 
 42 void da(int str[], int sa[], int rk[], int height[], int n, int m){
 43     n++;
 44     int i, j, p, *x = t1, *y = t2;
 45     for(i = 0; i < m; i++) c[i] = 0;
 46     for(i = 0; i < n; ++i) c[x[i] = str[i]]++;
 47     for(i = 1; i < m; ++i) c[i] += c[i - 1];
 48     for(i = n - 1; i >= 0; --i) sa[--c[x[i]]] = i;
 49     for(j = 1; j <= n; j <<= 1){
 50         p = 0;
 51         for(i = n - j; i < n; ++i) y[p++] = i;
 52         for(i = 0; i < n; ++i) if(sa[i] >= j) y[p++] = sa[i] - j;
 53         for(i = 0; i < m; ++i) c[i] = 0;
 54         for(i = 0; i < n; ++i) c[x[y[i]]]++;
 55         for(i = 1; i  < m; ++i) c[i] += c[i - 1];
 56         for(i = n - 1; i >= 0; --i) sa[--c[x[y[i]]]] = y[i];
 57         swap(x, y);
 58         p = 1; x[sa[0]] = 0;
 59         for(i = 1; i < n; ++i)
 60             x[sa[i]] = cmp(y, sa[i - 1], sa[i], j)? p - 1: p++;
 61         if(p >= n) break;
 62         m = p;
 63     }
 64     int k = 0;
 65     n--;
 66     for(i = 0; i <= n; ++i) rk[sa[i]] = i;
 67     for(i = 0; i <n ; ++i){
 68         if(k) k--;
 69         j = sa[rk[i] - 1];
 70         while(str[i + k] == str[j + k]) ++k;
 71         height[rk[i]] = k;
 72     }
 73 }
 74 
 75 int best[20][maxn], mm[maxn];
 76 int rk[maxn], height[maxn], RMQ[maxn],r[maxn];
 77 int sa[maxn];
 78 void initRMQ(int n){
 79     mm[0] = -1;
 80     for(int i = 1; i <= n; ++i)
 81         mm[i] = ((i&(i - 1)) == 0)?mm[i-1] + 1:mm[i-1];
 82     for(int i = 1; i <= n; ++i) best[0][i] = i;
 83     for(int i = 1; i <= mm[n]; ++i)
 84         for(int j = 1; j + (1 <<i) - 1 <= n; ++j){
 85             int a = best[i-1][j];
 86             int b = best[i-1][j+(1 << (i-1))];
 87             if(RMQ[a] < RMQ[b]) best[i][j] = a;
 88             else best[i][j] = b;
 89         }
 90 }
 91 
 92 int askRMQ(int a, int b){
 93     int t;
 94     t = mm[b - a + 1];
 95     b -= (1 << t) - 1;
 96     a = best[t][a]; b = best[t][b];
 97     return RMQ[a] < RMQ[b]?a:b;
 98 }
 99 
100 int lcp(int a, int b){
101     a = rk[a]; b = rk[b];
102     if(a > b) swap(a, b);
103     return height[askRMQ(a + 1, b)];
104 }
105 
106 int main(){
107     //freopen("data.in","r",stdin);
108     //freopen("data.out","w",stdout);
109     //cin.sync_with_stdio(false);
110     int cs = 0;
111     while(scanf("%s", s) != EOF && s[0] != '#'){
112         cs++;
113         int n = strlen(s);
114         for(int i = 0; i < n; ++i) r[i] = s[i];
115         r[n] = 0;
116         da(r, sa, rk, height, n, 200);
117         for(int i = 0; i <= n; ++i) RMQ[i] =  height[i];
118         initRMQ(n);
119         int ans = 0;
120         int tn = n << 1;
121         int arr[maxn],a, ret, t, re = 0,sl;
122         for(int l = 1; l <= tn; ++l){
123             for(int j = 0; j - l < n; j += l){
124                 sl = lcp(j, j + l);
125                 ret = sl / l + 1;
126                    t = l - sl%l;
127                 t = j - t;
128                 if(t>= 0&&sl%l){
129                     if(lcp(t, t + l) >= l)     ret++;
130                 }
131                 if(re < ret){
132                     re = ret;
133                     a = 0;
134                     arr[a++] = l;  // 将重复次数最大的l都存入arr数组中, 最后在一个个枚举,选择最大值
135                 }else if(re == ret){
136                     arr[a++] = l;
137                 }
138             }
139         }
140         int ansl = 0, ansi = sa[n];
141         for(int i = 0; i < a; ++i){
142             for(int j = 0; j + arr[i] < n; ++j){
143                 if(lcp(j, j + arr[i]) / arr[i] + 1 == re){
144                     if(rk[ansi] >  rk[j]){
145                         ansi = j;
146                         ansl = arr[i];
147                     }
148                 }
149             }
150         }
151         if(debug){
152             dg(ansl);
153             dg(ansi);
154             dg(re);
155         }
156         printf("Case %d: ", cs);
157         for(int i = ansi; i <ansi + ansl * re ; ++i){
158             printf("%c",s[i]);
159         }
160         printf("\n");
161     }
162     return 0;
163 }
View Code

 

4.求字符串的循环节的最大循环次数(用dc3,如果 kmp 也可以

 

  1 /*
  2 ***********Good LUCK**********
  3 * Author:  yeahpeng
  4 * Created Time:  2015/4/23 23:04:43
  5 * File Name: poj2406
  6 */
  7 #define _CRT_SECURE_NO_WARNINGS
  8 #include <stdio.h>
  9 #include <iostream>
 10 #include <algorithm>
 11 #include <sstream>
 12 #include <stdlib.h>
 13 #include <string.h>
 14 #include <limits.h>
 15 #include <vector>
 16 #include <string>
 17 #include <time.h>
 18 #include <math.h>
 19 #include <queue>
 20 #include <stack>
 21 #include <set>
 22 #include <map>
 23 #define INF 0x3f3f3f3f
 24 #define Zero(x)  memset((x),0, sizeof(x))
 25 #define Neg(x) memset((x), -1, sizeof(x))
 26 #define dg(x) cout << #x << " = " << x << endl
 27 #define pk(x)   push_back(x)
 28 #define pok()   pop_back()
 29 #define eps 1e-8
 30 #define pii pair<int, int>
 31 #define pi acos(-1.0)
 32 using namespace std;
 33 typedef long long ll;
 34 bool debug = false;
 35 int OK = 1;
 36 const int maxn = 1000100;
 37 #define F(x) ((x/3) + ((x) % 3 == 1? 0 : tb))
 38 #define G(x) ((x)<tb?(x)*3 + 1:((x)-tb)*3 + 2)
 39 int wa[maxn * 3], wb[maxn * 3], wv[maxn * 3], wss[maxn * 3], sa[maxn * 3], rk[maxn * 3];
 40 int c0(int *r, int a, int b){
 41     return r[a] == r[b] && r[a + 1] == r[b + 1] && r[a + 2] == r[b + 2];
 42 }
 43 
 44 int c12(int k, int *r, int a, int b){
 45     if (k == 2)
 46         return r[a] < r[b] || (r[a] == r[b] && c12(1, r, a + 1, b + 1));
 47     else return r[a] < r[b] || (r[a] == r[b] && wv[a + 1] < wv[b + 1]);
 48 }
 49 
 50 void sort(int *r, int *a, int *b, int n, int m){
 51     int i;
 52     for (i = 0; i < n; ++i) wv[i] = r[a[i]];
 53     for (i = 0; i < m; ++i) wss[i] = 0;
 54     for (i = 0; i < n; ++i) wss[wv[i]]++;
 55     for (i = 1; i < m; ++i) wss[i] += wss[i - 1];
 56     for (i = n - 1; i >= 0; --i)
 57         b[--wss[wv[i]]] = a[i];
 58 }
 59 
 60 void dc3(int * r, int *sa, int n, int m){
 61     int i, j, *rn = r + n;
 62     int *san = sa + n, ta = 0, tb = (n + 1) / 3, tbc = 0, p;
 63     r[n] = r[n + 1] = 0;
 64     for (i = 0; i < n; ++i) if (i % 3 != 0) wa[tbc++] = i;
 65     sort(r + 2, wa, wb, tbc, m);
 66     sort(r + 1, wb, wa, tbc, m);
 67     sort(r, wa, wb, tbc, m);
 68     for (p = 1, rn[F(wb[0])] = 0, i = 1; i < tbc; ++i)
 69         rn[F(wb[i])] = c0(r, wb[i - 1], wb[i]) ? p - 1 : p++;
 70     if (p < tbc) dc3(rn, san, tbc, p);
 71     else for (i = 0; i < tbc; i++) san[rn[i]] = i;
 72     for (i = 0; i <tbc; i++) if (san[i] < tb) wb[ta++] = san[i] * 3;
 73     if (n % 3 == 1) wb[ta++] = n - 1;
 74     sort(r, wb, wa, ta, m);
 75     for (i = 0; i < tbc; i++) wv[wb[i] = G(san[i])] = i;
 76     for (i = 0, j = 0, p = 0; i < ta && j < tbc; p++)
 77         sa[p] = c12(wb[j] % 3, r, wa[i], wb[j]) ? wa[i++] : wb[j++];
 78     for (; i < ta; p++) sa[p] = wa[i++];
 79     for (; j < tbc; p++) sa[p] = wb[j++];
 80 }
 81 
 82 void da(int str[], int sa[], int rk[], int height[], int  n, int m){
 83     for (int i = n; i < n + 3; i++)
 84         str[i] = 0;
 85     dc3(str, sa, n + 1, m);
 86     int i, j, k = 0;
 87     for (i = 0; i <= n; i++) rk[sa[i]] = i;
 88     for (i = 0; i < n; ++i){
 89         if (k) k--;
 90         j = sa[rk[i] - 1];
 91         while (str[i + k] == str[j + k]) k++;
 92         height[rk[i]] = k;
 93     }
 94 }
 95 char s[maxn];
 96 int n;
 97 int r[maxn * 3], height[maxn];
 98 int main(){
 99     //freopen("data.in","r",stdin);
100     //freopen("data.out","w",stdout);
101     //cin.sync_with_stdio(false);
102     while (scanf("%s", s) != EOF){
103         if (s[0] == '.') break;
104         n = strlen(s);
105         for (int i = 0; i < n; ++i) r[i] = s[i];
106         r[n] = 0;
107         da(r, sa, rk, height, n, 200);
108         if (debug){
109             for (int i = 0; i < n; ++i)
110                 cout << rk[i] << " ";
111             cout << endl;
112             for (int i = 2; i <= n; ++i)
113                 cout << height[i] << " ";
114             cout << endl;
115         }
116         for (int i = 1; i <= n; ++i){
117             if (n % i == 0){
118                 int from = rk[i], to = rk[0];
119                 if (debug){
120                     dg(from);
121                     dg(to);
122                 }
123                 if (from > to) swap(from, to); // 判断sufffix(0) 和 sufficx(k)的公共前缀是否等于  n - k
124                 if (n == i || height[to] == n - i){
125                     printf("%d\n", n / i);
126                     break;
127                 }
128             }
129         }
130     }
131     return 0;
132 }
View Code

 

5.字符串中不同子串的个数

 

 

  1 /*
  2  ***********Good LUCK**********
  3  * Author:  yeahpeng
  4  * Created Time:  2015/4/23 19:35:41
  5  * File Name: spoj705.cpp
  6  */
  7 #include <stdio.h>
  8 #include <iostream>
  9 #include <algorithm>
 10 #include <sstream>
 11 #include <stdlib.h>
 12 #include <string.h>
 13 #include <limits.h>
 14 #include <vector>
 15 #include <string>
 16 #include <time.h>
 17 #include <math.h>
 18 #include <queue>
 19 #include <stack>
 20 #include <set>
 21 #include <map>
 22 #define INF 0x3f3f3f3f
 23 #define Zero(x)  memset((x),0, sizeof(x))
 24 #define Neg(x) memset((x), -1, sizeof(x))
 25 #define dg(x) cout << #x << " = " << x << endl
 26 #define pk(x)   push_back(x)
 27 #define pok()   pop_back()
 28 #define eps 1e-8
 29 #define pii pair<int, int>
 30 #define pi acos(-1.0)
 31 using namespace std;
 32 typedef long long ll;
 33 bool debug = false;
 34 const int maxn = 50500;
 35 int OK = 1;
 36 char s[maxn];
 37 int r[maxn], sa[maxn], rk[maxn], t1[maxn], t2[maxn];
 38 int c[maxn], height[maxn];
 39 int n;
 40 
 41 bool cmp(int *r, int a,int b, int l){
 42     return r[a] == r[b] && r[a + l] == r[b + l];
 43 }
 44 
 45 void da(int str[], int sa[], int rk[], int height[], int n, int m){
 46     n++;
 47     int i, j, p, *x = t1, *y = t2;
 48     for(i = 0; i < m; i++) c[i] = 0;
 49     for(i = 0; i < n; ++i) c[x[i] = str[i]]++;
 50     for(i = 1; i < m; ++i) c[i] += c[i - 1];
 51     for(i = n - 1; i >= 0; --i) sa[--c[x[i]]] = i;
 52     for(j = 1; j <= n; j <<= 1){
 53         p = 0;
 54         for(i = n - j; i < n; ++i) y[p++] = i;
 55         for(i = 0; i < n; ++i) if(sa[i] >= j) y[p++] = sa[i] - j;
 56         for(i = 0; i < m; ++i) c[i] = 0;
 57         for(i = 0; i < n; ++i) c[x[y[i]]]++;
 58         for(i = 1; i  < m; ++i) c[i] += c[i - 1];
 59         for(i = n - 1; i >= 0; --i) sa[--c[x[y[i]]]] = y[i];
 60         swap(x, y);
 61         p = 1; x[sa[0]] = 0;
 62         for(i = 1; i < n; ++i)
 63             x[sa[i]] = cmp(y, sa[i - 1], sa[i], j)? p - 1: p++;
 64         if(p >= n) break;
 65         m = p;
 66     }
 67     int k = 0;
 68     n--;
 69     for(i = 0; i <= n; ++i) rk[sa[i]] = i;
 70     for(i = 0; i <n ; ++i){
 71         if(k) k--;
 72         j = sa[rk[i] - 1];
 73         while(str[i + k] == str[j + k]) ++k;
 74         height[rk[i]] = k;
 75     }
 76 }
 77 
 78 int main(){
 79     //freopen("data.in","r",stdin);
 80     //freopen("data.out","w",stdout);
 81     //cin.sync_with_stdio(false);
 82     int T;
 83     scanf("%d", &T);
 84     for(int i = 0; i < T; ++i){
 85         scanf("%s", s);
 86         n = strlen(s);
 87         for(int i = 0; i < n; ++i) r[i] = s[i];
 88         r[n] = 0;
 89         da(r, sa,rk, height, n, 200);
 90         int ans = 0;
 91     if(debug){
 92         for(int i = 0; i <= n; ++i)
 93             cout << height[i] << " ";
 94         cout << endl;
 95         for(int i = 1; i <= n; ++i)
 96             cout << sa[i] << " ";
 97         cout << endl;
 98     }
 99         ans += n - sa[1];
100 
101         height[n + 1] = 0;
102         for(int i = 2; i <= n; ++i){
103             ans += n - sa[i] - height[i];
104         if(debug){
105             dg(n - sa[i]);
106             dg(sa[i]);
107             dg(height[i]);
108             dg(ans);
109         }
110         }
111         printf("%d\n", ans);
112     }    
113     return 0;
114 }
View Code

 

 

 

6.重复次数最多的连续重复子串

  1 /*
  2  ***********Good LUCK**********
  3  * Author:  yeahpeng
  4  * Created Time:  2015/4/24 21:44:34
  5  * File Name: poj3693.cpp
  6  */
  7 #include <stdio.h>
  8 #include <iostream>
  9 #include <algorithm>
 10 #include <sstream>
 11 #include <stdlib.h>
 12 #include <string.h>
 13 #include <limits.h>
 14 #include <vector>
 15 #include <string>
 16 #include <time.h>
 17 #include <math.h>
 18 #include <queue>
 19 #include <stack>
 20 #include <set>
 21 #include <map>
 22 #define INF 0x3f3f3f3f
 23 #define Zero(x)  memset((x),0, sizeof(x))
 24 #define Neg(x) memset((x), -1, sizeof(x))
 25 #define dg(x) cout << #x << " = " << x << endl
 26 #define pk(x)   push_back(x)
 27 #define pok()   pop_back()
 28 #define eps 1e-8
 29 #define pii pair<int, int>
 30 #define pi acos(-1.0)
 31 using namespace std;
 32 typedef long long ll;
 33 bool debug = false;
 34 int OK = 1;
 35 const int maxn = 100100;
 36 char s[maxn];
 37 int t1[maxn], t2[maxn], c[maxn];
 38 bool cmp(int *r, int a,int b, int l){
 39     return r[a] == r[b] && r[a + l] == r[b + l];
 40 }
 41 
 42 void da(int str[], int sa[], int rk[], int height[], int n, int m){
 43     n++;
 44     int i, j, p, *x = t1, *y = t2;
 45     for(i = 0; i < m; i++) c[i] = 0;
 46     for(i = 0; i < n; ++i) c[x[i] = str[i]]++;
 47     for(i = 1; i < m; ++i) c[i] += c[i - 1];
 48     for(i = n - 1; i >= 0; --i) sa[--c[x[i]]] = i;
 49     for(j = 1; j <= n; j <<= 1){
 50         p = 0;
 51         for(i = n - j; i < n; ++i) y[p++] = i;
 52         for(i = 0; i < n; ++i) if(sa[i] >= j) y[p++] = sa[i] - j;
 53         for(i = 0; i < m; ++i) c[i] = 0;
 54         for(i = 0; i < n; ++i) c[x[y[i]]]++;
 55         for(i = 1; i  < m; ++i) c[i] += c[i - 1];
 56         for(i = n - 1; i >= 0; --i) sa[--c[x[y[i]]]] = y[i];
 57         swap(x, y);
 58         p = 1; x[sa[0]] = 0;
 59         for(i = 1; i < n; ++i)
 60             x[sa[i]] = cmp(y, sa[i - 1], sa[i], j)? p - 1: p++;
 61         if(p >= n) break;
 62         m = p;
 63     }
 64     int k = 0;
 65     n--;
 66     for(i = 0; i <= n; ++i) rk[sa[i]] = i;
 67     for(i = 0; i <n ; ++i){
 68         if(k) k--;
 69         j = sa[rk[i] - 1];
 70         while(str[i + k] == str[j + k]) ++k;
 71         height[rk[i]] = k;
 72     }
 73 }
 74 
 75 int best[20][maxn], mm[maxn];
 76 int rk[maxn], height[maxn], RMQ[maxn],r[maxn];
 77 int sa[maxn];
 78 void initRMQ(int n){
 79     mm[0] = -1;
 80     for(int i = 1; i <= n; ++i)
 81         mm[i] = ((i&(i - 1)) == 0)?mm[i-1] + 1:mm[i-1];
 82     for(int i = 1; i <= n; ++i) best[0][i] = i;
 83     for(int i = 1; i <= mm[n]; ++i)
 84         for(int j = 1; j + (1 <<i) - 1 <= n; ++j){
 85             int a = best[i-1][j];
 86             int b = best[i-1][j+(1 << (i-1))];
 87             if(RMQ[a] < RMQ[b]) best[i][j] = a;
 88             else best[i][j] = b;
 89         }
 90 }
 91 
 92 int askRMQ(int a, int b){
 93     int t;
 94     t = mm[b - a + 1];
 95     b -= (1 << t) - 1;
 96     a = best[t][a]; b = best[t][b];
 97     return RMQ[a] < RMQ[b]?a:b;
 98 }
 99 
100 int lcp(int a, int b){
101     a = rk[a]; b = rk[b];
102     if(a > b) swap(a, b);
103     return height[askRMQ(a + 1, b)];
104 }
105 
106 int main(){
107     //freopen("data.in","r",stdin);
108     //freopen("data.out","w",stdout);
109     //cin.sync_with_stdio(false);
110     int cs = 0;
111     while(scanf("%s", s) != EOF && s[0] != '#'){
112         cs++;
113         int n = strlen(s);
114         for(int i = 0; i < n; ++i) r[i] = s[i];
115         r[n] = 0;
116         da(r, sa, rk, height, n, 200);
117         for(int i = 0; i <= n; ++i) RMQ[i] =  height[i];
118         initRMQ(n);
119         int ans = 0;
120         int tn = n << 1;
121         int arr[maxn],a, ret, t, re = 0,sl;
122         for(int l = 1; l <= tn; ++l){
123             for(int j = 0; j - l < n; j += l){
124                 sl = lcp(j, j + l);
125                 ret = sl / l + 1;
126                    t = l - sl%l;
127                 t = j - t;
128                 if(t>= 0&&sl%l){
129                     if(lcp(t, t + l) >= l)     ret++;
130                 }
131                 if(re < ret){
132                     re = ret;
133                     a = 0;
134                     arr[a++] = l;  // 将重复次数最大的l都存入arr数组中, 最后在一个个枚举,选择最大值
135                 }else if(re == ret){
136                     arr[a++] = l;
137                 }
138             }
139         }
140         int ansl = 0, ansi = sa[n];
141         for(int i = 0; i < a; ++i){
142             for(int j = 0; j + arr[i] < n; ++j){
143                 if(lcp(j, j + arr[i]) / arr[i] + 1 == re){
144                     if(rk[ansi] >  rk[j]){
145                         ansi = j;
146                         ansl = arr[i];
147                     }
148                 }
149             }
150         }
151         if(debug){
152             dg(ansl);
153             dg(ansi);
154             dg(re);
155         }
156         printf("Case %d: ", cs);
157         for(int i = ansi; i <ansi + ansl * re ; ++i){
158             printf("%c",s[i]);
159         }
160         printf("\n");
161     }
162     return 0;
163 }
View Code
posted @ 2015-04-28 00:00  yeahpeng  阅读(359)  评论(0编辑  收藏  举报