zoukankan      html  css  js  c++  java
  • bzoj 3676 [Apio2014]回文串 回文自动机

    [Apio2014]回文串

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 3428  Solved: 1580
    [Submit][Status][Discuss]

    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

    HINT



    一个串是回文的,当且仅当它从左到右读和从右到左读完全一样。 

    在第一个样例中,回文子串有7个:a,b,c,aba,aca,bacab,abacaba,其中: 

    ● a出现4次,其出现值为4:1:1=4 

    ● b出现2次,其出现值为2:1:1=2 

    ● c出现1次,其出现值为l:1:l=l 

    ● aba出现2次,其出现值为2:1:3=6 

    ● aca出现1次,其出现值为1=1:3=3 

    ●bacab出现1次,其出现值为1:1:5=5 

    ● abacaba出现1次,其出现值为1:1:7=7 

    故最大回文子串出现值为7。 

    【数据规模与评分】 

    数据满足1≤字符串长度≤300000。

    Source

     题解:回文自动机模板题
     1 #include<cstring>
     2 #include<algorithm>
     3 #include<cmath>
     4 #include<iostream>
     5 #include<cstdio>
     6 
     7 #define N 300007
     8 #define ll long long
     9 using namespace std;
    10 inline int read()
    11 {
    12     int x=0,f=1;char ch=getchar();
    13     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    14     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    15     return x*f;
    16 }
    17 
    18 int n;ll ans;
    19 char ch[N];
    20 struct pam
    21 {
    22     int cnt,last;
    23     int c[N][26],fa[N],len[N],siz[N];
    24     pam()
    25     {
    26         cnt=1;
    27         fa[0]=fa[1]=1;
    28         len[1]=-1;
    29     }
    30     void extend(int x,int n)
    31     {
    32         int p=last;
    33         while(ch[n-len[p]-1]!=ch[n])p=fa[p];
    34         if(!c[p][x])
    35         {
    36             int now=++cnt,k=fa[p];
    37             len[now]=len[p]+2;
    38             while(ch[n-len[k]-1]!=ch[n])k=fa[k];
    39             fa[now]=c[k][x],c[p][x]=now;
    40         }
    41         last=c[p][x];
    42         siz[last]++;
    43     }
    44     void solve()
    45     {
    46         for (int i=cnt;i>=1;i--)
    47         {
    48             siz[fa[i]]+=siz[i];
    49             ans=max(ans,(ll)siz[i]*len[i]);
    50         }
    51     }
    52 }pam;
    53 
    54 int main()
    55 {
    56     scanf("%s",ch+1);n=strlen(ch+1);
    57     for (int i=1;i<=n;i++)
    58         pam.extend(ch[i]-'a',i);
    59     pam.solve();
    60     printf("%lld
    ",ans);
    61 }
  • 相关阅读:
    洛谷P4979 矿洞:坍塌
    [SHOI2015]脑洞治疗仪
    洛谷P2135 方块消除
    洛谷P1436 棋盘分割
    洛谷P2796 Facer的程序
    浅谈位运算
    [SDOI2006]最短距离
    12耐心_预测未来
    11耐心_有效市场假说
    02C++条件变量
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8847993.html
Copyright © 2011-2022 走看看