标签:style blog http color os io strong for ar
Jane loves string more than anything. She made a function related to the string some days ago and forgot about it. She is now confused about calculating the value of this function. She has a string T with her, and value of string S over function f can be calculated as given below:
f(S)=|S|∗NumberoftimesSoccuringinTJane wants to know the maximum value of f(S) among all the substrings (S) of string T. Can you help her?
Input Format
A single line containing string T in small letter(‘a‘ - ‘z‘).Output Format
An integer containing the value of output.Constraints
1 ≤|T|≤ 105Sample Input #00
aaaaaa
Sample Output #00
12
Explanation #00
f(‘a‘) = 6 f(‘aa‘) = 10 f(‘aaa‘) = 12 f(‘aaaa‘) = 12 f(‘aaaaa‘) = 10 f(‘aaaaaa‘) = 6
Sample Input #01
abcabcddd
Sample Output #01
9
Explanation #01
f("a") = 2 f("b") = 2 f("c") = 2 f("ab") = 4 f("bc") = 4 f("ddd") = 3 f("abc") = 6 f("abcabcddd") = 9
Among the function values 9 is the maximum one.
题意:求字符串所有子串中,f(s)的最大值。这里s是某个子串,f(s) = s的长度与s在原字符串中出现次数的乘积。
求得lcp, 转化为求以lcp为高的最大子矩形。
Accepted Code:
1 #include <string>
2 #include <iostream>
3 #include <algorithm>
4 using namespace std;
5
6 const int MAX_N = 100002;
7 int sa[MAX_N], rk[MAX_N], lcp[MAX_N], tmp[MAX_N], n, k;
8
9 bool compare_sa(int i, int j) {
10 if (rk[i] != rk[j]) return rk[i] < rk[j];
11 int ri = i + k <= n ? rk[i + k] : -1;
12 int rj = j + k <= n ? rk[j + k] : -1;
13 return ri < rj;
14 }
15
16 void construct_sa(const string &S, int *sa) {
17 n = S.length();
18 for (int i = 0; i <= n; i++) {
19 sa[i] = i;
20 rk[i] = i < n ? S[i] : -1;
21 }
22
23 for (k = 1; k <= n; k *= 2) {
24 sort(sa, sa + n + 1, compare_sa);
25
26 tmp[sa[0]] = 0;
27 for (int i = 1; i <= n; i++) {
28 tmp[sa[i]] = tmp[sa[i - 1]] + (compare_sa(sa[i - 1], sa[i]) ? 1 : 0);
29 }
30 for (int i = 0; i <= n; i++) rk[i] = tmp[i];
31 }
32 }
33
34 void construct_lcp(const string &S, int *sa, int *lcp) {
35 n = S.length();
36 for (int i = 0; i <= n; i++) rk[sa[i]] = i;
37
38 int h = 0;
39 lcp[0] = 0;
40 for (int i = 0; i < n; i++) {
41 int j = sa[rk[i] - 1];
42
43 if (h > 0) h--;
44 for (; i + h < n && j + h < n; h++) if (S[i + h] != S[j + h]) break;
45
46 lcp[rk[i] - 1] = h;
47 }
48 }
49
50 string S;
51 int lft[MAX_N], rgt[MAX_N], st[MAX_N], top;
52 void solve() {
53 construct_sa(S, sa);
54 construct_lcp(S, sa, lcp);
55
56 lcp[n] = n - sa[n];
57 // for (int i = 1; i <= n; i++) cerr << lcp[i] << ‘ ‘;
58 // cerr << endl;
59 top = 0;
60 for (int i = 1; i <= n; i++) {
61 while (top && lcp[st[top-1]] >= lcp[i]) top--;
62 if (top) lft[i] = st[top - 1] + 1;
63 else lft[i] = 1;
64 st[top++] = i;
65 }
66 top = 0;
67 for (int i = n; i > 0; i--) {
68 while (top && lcp[st[top-1]] >= lcp[i]) top--;
69 // attention: rgt[i] should be asigned to st[top - 1]
70 // rather than st[top - 1] - 1 because lcp[i] is the
71 // length of the longest common prefix of sa[i] and sa[i + 1].
72 if (top) rgt[i] = st[top - 1];
73 else rgt[i] = n;
74 st[top++] = i;
75 }
76 long long ans = n;
77 for (int i = 1; i <= n; i++) ans = max(ans, (long long)lcp[i] * (rgt[i] - lft[i] + 1));
78 cout << ans << endl;
79 }
80
81 int main(void) {
82 //ios::sync_with_std(false);
83 while (cin >> S) solve();
84 return 0;
85 }
Hackerrank--String Function Calculation(后缀数组)
标签:style blog http color os io strong for ar
原文地址:http://www.cnblogs.com/Stomach-ache/p/3930096.html