Hackerrank--String Function Calculation(后缀数组)

题目链接

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|∗NumberoftimesSoccuringinT

Jane 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|≤ 105

Sample 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 }
时间: 2024-10-02 01:41:40

Hackerrank--String Function Calculation(后缀数组)的相关文章

HDU5008 Boring String Problem(后缀数组 + 二分 + 线段树)

题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5008 Description In this problem, you are given a string s and q queries. For each query, you should answer that when all distinct substrings of string s were sorted lexicographically, which one is

HDU5853 Jong Hyok and String(二分 + 后缀数组)

题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5853 Description Jong Hyok loves strings. One day he gives a problem to his friend you. He writes down n strings Pi in front of you, and asks m questions. For i-th question, there is a string Qi. We

hdu 5030 Rabbit&#39;s String(后缀数组&amp;二分)

Rabbit's String Time Limit: 40000/20000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 288    Accepted Submission(s): 108 Problem Description Long long ago, there lived a lot of rabbits in the forest. One day, the

POJ 2406 Power String 后缀数组

这题曾经用KMP做过,用KMP 做非常的简单,h函数自带的找循环节功能. 用后缀数组的话,首先枚举循环节长度k,然后比较LCP(suffix(k + 1), suffix(0)) 是否等于len - k, 如果相等显然k就是一个循环节. 得到LCP的话可以通过预处理出所有点和0的lcp就好了.另外倍增法构造后缀数组还有用RMQ来搞lcp nlogn是不行的,会超时,所以可以dc3走起了.. #include <cstdio> #include <cstring> #include

hdu 5008(2014 ACM/ICPC Asia Regional Xi&#39;an Online ) Boring String Problem(后缀数组&amp;二分)

Boring String Problem Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 219    Accepted Submission(s): 45 Problem Description In this problem, you are given a string s and q queries. For each que

hdu 6194 string string string(后缀数组)

题目链接:hdu 6194 string string string 题意: 给你一个字符串,给你一个k,问你有多少个子串恰好在原串中出现k次. 题解: 后缀数组求出sa后,用height数组的信息去找答案. 每次用k长度的区间去卡height数组,求出该区间的lcp. 该区间的贡献就是ans=lcp-max(height[i],height[i+k]). 如果ans<=0,就不贡献. 比如 2 aaa 后缀数组为: 1 a 2 aa 3 aaa height为 0,1,2 现在扫到[1,2],

hdu 5030 Rabbit&#39;s String(后缀数组)

题目链接:hdu 5030 Rabbit's String 题目大意:给定k和一个字符串,要求将字符串拆分成k个子串.然后将每个子串中字典序最大的子串选出来,组成一个包含k个字符串的集合,要求这个集合中字典序最大的字符串字典序最小. 解题思路:网赛的时候试图搞了一下这道题,不过水平还是有限啊,后缀数组也是初学,只会切一些水题.赛后看了一下别人的题解,把这题补上了. 首先对整个字符串做后缀数组,除了处理出sa,rank,height数组,还要处理处f数组,f[i]表示说以0~sa[i]开头共有多少

hdu 6194 沈阳网络赛--string string string(后缀数组)

题目链接 Problem Description Uncle Mao is a wonderful ACMER. One day he met an easy problem, but Uncle Mao was so lazy that he left the problem to you. I hope you can give him a solution.Given a string s, we define a substring that happens exactly k time

POJ 3729 Facer’s string (后缀数组)

题目大意: 串1中有多少个后缀和 串2中的某个后缀 的lcp 为 k 思路分析: 先找出 长度至少为k的对数有多少. 再找出 至少为k+1的有多少 然后相减. #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <map> #include <string> #define maxn 110005 using na