zoukankan      html  css  js  c++  java
  • 后缀数组题目整理

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

    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("
    ");
    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 / 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
    ", 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("
    ");
    161     }
    162     return 0;
    163 }
    View Code
  • 相关阅读:
    转:CSS设置HTML元素的高度与宽度的各种情况总结
    Java、mysql、html、css、js 注释&大小写
    Dom4j与sax 简单对比
    转:Java properties | FileNotFoundException: properties (系统找不到指定的文件。)
    转:SAX解析的characters方法被多次调用
    转:HashMap实现原理分析(面试问题:两个hashcode相同 的对象怎么存入hashmap的)
    转:Scanner中nextLine()方法和next()方法的区别
    转:JDBC中关于PreparedStatement.setObject的一些细节说明
    转:Eclipse 各种小图标的含义
    转:Mysql float类型where 语句判断相等问题
  • 原文地址:https://www.cnblogs.com/yeahpeng/p/4461826.html
Copyright © 2011-2022 走看看