zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    SharePoint 2013 图文开发系列之自定义字段
    SharePoint 2013 图文开发系列之Visual Studio 创建母版页
    SharePoint 2013 图文开发系列之代码定义列表
    SharePoint 2013 图文开发系列之计时器任务
    SharePoint 2013 图文开发系列之应用程序页
    SharePoint 2013 图文开发系列之事件接收器
    SharePoint 2013 图文开发系列之可视化WebPart
    SharePoint 2013 图文开发系列之WebPart
    SharePoint 2013 对二进制大型对象(BLOB)进行爬网
    SharePoint 2013 状态机工作流之日常报销示例
  • 原文地址:https://www.cnblogs.com/Stomach-ache/p/3930096.html
Copyright © 2011-2022 走看看