zoukankan      html  css  js  c++  java
  • [回文树]JZOJ P3654 回文串

    Description

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

    Input

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

    Output

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

    Sample Input

    输入1:

    abacaba

    输入2:

    www

    Sample Output

    输出1:

    7

    输出2:

    4

    Hint
    这里写图片描述
    这里写图片描述

    题解

        听题时一脸懵逼,只见dalao什么fail指针连来连去的,目光呆滞的看着黑板(其实心里默默问候了出题人全家)
        首先,这是一颗几乎是裸的回文树
    !!但是!!
        回文树是什么?又怎么去实现?
        只好找呀,但基本上没几个看懂的
        最后找到一个Victor Wonder dalao%%%
        才勉强对着标看懂
        具体,我也不怎么会说,自行看dalao写的pdf脑补
    

    链接
    链接
    (第二个比较详细)

    代码

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<algorithm>
    using namespace std;
    int next[300005][30],fail[300005],len[300005],bz[300005],last,n,tot;;
    long long cnt[300005]; 
    string s;
    void newnode(int l)
    {
        ++tot;
        for (int i=1;i<=26;i++) next[tot][i]=0;
        len[tot]=l;
        cnt[tot]=0;
    }
    int get_fail(int x)
    {
        while (bz[n-len[x]-1]!=bz[n]) x=fail[x];
        return x;
    }
    void add(char x)
    {
        int c=x-'a'+1;
        bz[++n]=c;
        int cur=get_fail(last);
        if (!next[cur][c])
        {
            newnode(len[cur]+2);
            fail[tot]=next[get_fail(fail[cur])][c];
            next[cur][c]=tot;
        }
        last=next[cur][c];
        cnt[last]++;
    }
    void count() { for (int i=tot;i>=0;i--) cnt[fail[i]]+=cnt[i]; }
    int main()
    {
        freopen("palindrome.in","r",stdin);
        freopen("palindrome.out","w",stdout);
        cin>>s;
        tot=-1; bz[n]=-1; fail[0]=1; 
        newnode(0);
        newnode(-1);
        for (int i=0;i<s.length();i++) add(s[i]);
        count();
        long long ans=0;
        for (int i=2;i<=tot;i++)
        {
            long long k=cnt[i]*len[i];
            if (k>ans) ans=k;
        }
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    02注册Github账户
    软件工程概论第一节
    01课堂测试
    第二阶段冲刺01
    在子类中,若要调用父类中被覆盖的方法,可以使用super关键字
    动手动脑
    springBoot学习 错误记录
    什么是Hadoop?什么是HDFS?
    springCloud当中Eureca sever当中Camden到底是什么?
    Eureca Server的Helloworld例子
  • 原文地址:https://www.cnblogs.com/Comfortable/p/8412233.html
Copyright © 2011-2022 走看看