• BZOJ3676: [Apio2014]回文串


    Description

    考虑一个只包含小写拉丁字母的字符串s。我们定义s的一个子串t的“出
    现值”为t在s中的出现次数乘以t的长度。请你求出s的所有回文子串中的最
    大出现值。

    Input

    输入只有一行,为一个只包含小写字母(a -z)的非空字符串s。

    Output


    输出一个整数,为逝查回文子串的最大出现值。

    Sample Input

    【样例输入l】
    abacaba

    【样例输入2]
    www

    Sample Output

    【样例输出l】
    7

    【样例输出2]
    4

    回文树模板题,虽然知道可以在SAM上倍增爆搞

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int N=300010;
     5 struct PAM{
     6     int cnt,last;
     7     int a[N][26],sz[N],l[N],f[N];
     8     char s[N];
     9     PAM(){
    10         cnt=f[0]=f[1]=1;
    11         l[1]=-1;
    12     }
    13     int get_fail(int x,int loc){
    14         while(s[loc-l[x]-1]!=s[loc])x=f[x];
    15         return x;
    16     }
    17     void insert(int c,int loc){
    18         int p=get_fail(last,loc);
    19         if(!a[p][c]){
    20             int now=++cnt,k=get_fail(f[p],loc);
    21             l[now]=l[p]+2;
    22             f[now]=a[k][c];a[p][c]=now;
    23         }
    24         last=a[p][c];
    25         ++sz[last];
    26     }
    27     ll calc(){
    28         ll res=0;
    29         for(int i=cnt;i;--i){
    30             sz[f[i]]+=sz[i];
    31             res=max(res,(ll)sz[i]*l[i]);
    32         }
    33         return res;
    34     }
    35 }P;
    36 int main(){
    37     scanf("%s",P.s);
    38     int n=strlen(P.s);
    39     for(int i=0;i<n;++i)
    40         P.insert(P.s[i]-'a',i);
    41     printf("%lld
    ",P.calc());
    42     return 0;
    43 }
  • 相关阅读:
    bzoj4864 [BeiJing 2017 Wc]神秘物质
    HNOI2011 括号修复
    bzoj2402 陶陶的难题II
    ZJOI2008 树的统计
    USACO09JAN 安全出行Safe Travel
    HAOI2015 树上操作
    hdu5126 stars
    BOI2007 Mokia 摩基亚
    SDOI2011 拦截导弹
    国家集训队 排队
  • 原文地址:https://www.cnblogs.com/ndqzhang1111/p/6907505.html
Copyright © 2020-2023  润新知