码迷,mamicode.com
首页 > 编程语言 > 详细

后缀数组题目整理

时间:2015-04-28 01:51:30      阅读:238      评论:0      收藏:0      [点我收藏+]

标签:

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

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.不可重叠最长不重复子串( 二分长度k, height数组划分)

 

技术分享
  1 /*
  2  ***********Good LUCK**********
  3  * Author:  yeahpeng
  4  * Created Time:  2015/4/23 0:40:41
  5  * File Name: poj 1743.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 = 22000;
 36 int n, r[maxn], sa[maxn], height[maxn], rk[maxn];
 37 int t1[maxn], t2[maxn], c[maxn];
 38 
 39 bool cmp(int *r, int a, int b, int l){
 40     return r[a] == r[b] && r[a + l] == r[b + l];
 41 }
 42 
 43 void da(int str[], int sa[], int rk[], int height[], int n, int m){
 44     n++;
 45     int i, j, p, *x = t1, *y = t2;
 46     for(i = 0; i < m; i++) c[i] = 0;
 47     for(i = 0; i < n; ++i) c[x[i] = str[i]]++;
 48     for(i = 1; i < m; ++i) c[i] += c[i - 1];
 49     for(i = n - 1; i >= 0; --i) sa[--c[x[i]]] = i;
 50     for(j = 1; j <= n; j <<= 1){
 51         p = 0;
 52         for(i = n - j; i < n; ++i) y[p++] = i;
 53         for(i = 0; i < n; ++i) if(sa[i] >= j) y[p++] = sa[i] - j;
 54         for(i = 0; i < m; ++i) c[i] = 0;
 55         for(i = 0; i < n; ++i) c[x[y[i]]]++;
 56         for(i = 1; i  < m; ++i) c[i] += c[i - 1];
 57         for(i = n - 1; i >= 0; --i) sa[--c[x[y[i]]]] = y[i];
 58         swap(x, y);
 59         p = 1; x[sa[0]] = 0;
 60         for(i = 1; i < n; ++i)
 61             x[sa[i]] = cmp(y, sa[i - 1], sa[i], j)? p - 1: p++;
 62         if(p >= n) break;
 63         m = p;
 64     }
 65     int k = 0;
 66     n--;
 67     for(i = 0; i <= n; ++i) rk[sa[i]] = i;
 68     for(i = 0; i <n ; ++i){
 69         if(k) k--;
 70         j = sa[rk[i] - 1];
 71         while(str[i + k] == str[j + k]) ++k;
 72         height[rk[i]] = k;
 73     }
 74 }
 75 
 76 void getmxn(int mx, int mn, int j){
 77         mx = max(mx, sa[j]);
 78         mx = max(mx, sa[j - 1]);
 79         mn = min(mn, sa[j]);
 80         mn = min(mn, sa[j - 1]);
 81 }
 82 
 83 bool check(int k){
 84     int j = 2;
 85     while(1){
 86         int mx = 0, mn = n;
 87         while(j <= n){
 88             if(height[j] >= k) break;
 89             j++;
 90         }
 91         if(j > n) break;
 92         getmxn(mx, mn, j);
 93         while(j <= n){
 94             if(height[j] >= k) {
 95                 getmxn(mx, mn, j);
 96                 ++j;
 97                 continue;
 98             }
 99             break;
100         }
101         if(mx - mn >= k) return true;
102         j++;
103     }
104     return false;
105 }
106 const int nn = 89;
107 int main(){
108     //freopen("data.in","r",stdin);
109     //freopen("data.out","w",stdout);
110     //cin.sync_with_stdio(false);
111     while(scanf("%d", &n) != EOF){
112         if(!n) break;
113         int pv;
114         scanf("%d", &pv);
115         int v;
116         for(int i = 0; i < n - 1; ++i){
117             scanf("%d" , &v);
118             r[i] = v - pv + nn;
119             pv = v;
120     
121         }
122         r[n - 1] =  0;
123         n--;
124         da(r, sa, rk, height, n, nn * 2 );
125         int l = 1, h = n/ 2, mid;         
126         while(l <= h){
127             mid = (l + h) >> 1;
128             if(check(mid))    l = mid + 1;
129             else h = mid - 1;    
130         }
131         if(l >= 4){
132             printf("%d\n", l);
133         }else{
134             printf("0\n");
135         }
136     }    
137     return 0;
138 }
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

后缀数组题目整理

标签:

原文地址:http://www.cnblogs.com/yeahpeng/p/4461826.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!