zoukankan      html  css  js  c++  java
  • BZOJ3676: [Apio2014]回文串

    【传送门:BZOJ3676


    简要题意:

      给出一个字符串,每一个回文子串的价值为这个回文子串出现的次数*回文子串的长度,求出价值最大的回文子串的价值


    题解:

      %%%又是一道新算法

      本来想用AC自动机+马拉车搞一下的,结果不会

      hzwer大佬的题解用了后缀自动机+马拉车

      但是后缀自动机太难了

      这时引出我们的新算法——回文树

      算法详解,以及推荐代码风格

      简单来说,回文树可以解决以下问题:

      1.求串S前缀0~i内本质不同回文串的个数(两个串长度不同或者长度相同且至少有一个字符不同便是本质不同)
      2.求串S内每一个本质不同回文串出现的次数
      3.求串S内回文串的个数(其实就是1和2结合起来)
      4.求以下标i结尾的回文串的个数

      几乎很多回文问题均可解决

      而这道题就是回文树裸题了,直接在加入节点是顺便统计一下个数,最后按fail边自下而上更新一下即可


    参考代码:

    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstdlib>
    using namespace std;
    typedef long long LL;
    struct Tree
    {
        int len,fail,son[26];
    }tr[310000];
    char st[310000];
    int len,last,tot,cnt[310000];
    void ready()
    {
        tr[0].len=0;tr[1].len=-1;
        tr[0].fail=1;
        tot=1;last=0;
    }
    int findfail(int i,int j)
    {
        while(st[i-tr[j].len-1]!=st[i]) j=tr[j].fail;
        return j;
    }
    void add(int i,int x)
    {
        int j=findfail(i,last);
        if(tr[j].son[x]==0)
        {
            tr[++tot].len=tr[j].len+2;
            tr[tot].fail=tr[findfail(i,tr[j].fail)].son[x];
            tr[j].son[x]=tot;
        }
        last=tr[j].son[x];
        cnt[last]++;
    }
    LL getans()
    {
        LL ans=0;
        for(int i=tot;i>1;i--)
        {
            cnt[tr[i].fail]+=cnt[i];
            ans=max(ans,LL(tr[i].len)*LL(cnt[i]));
        }
        return ans;
    }
    int main()
    {
        scanf("%s",st+1);
        len=strlen(st+1);
        ready();
        for(int i=1;i<=len;i++) add(i,st[i]-'a');
        printf("%lld",getans());
    }

     

  • 相关阅读:
    数据结构与算法——红黑树
    JAVA数据结构——Map之HashMap
    JAVA数据结构——集合之LinkedList
    在Mac OS X下让你的Terminal带上Color
    Git使用指南(一)
    《乔布斯传》摘录
    必应语音API(Bing text to speech API)
    《设计心理学2》 摘录
    《设计心理学1》 摘录
    第10组 Beta冲刺(4/4)
  • 原文地址:https://www.cnblogs.com/Never-mind/p/8483018.html
Copyright © 2011-2022 走看看