zoukankan      html  css  js  c++  java
  • HYSBZ 3676 回文串 (回文树)

    3676: [Apio2014]回文串

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 1680  Solved: 707
    [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
    回文树模板题
    #include <iostream>
    #include <string.h>
    #include <algorithm>
    #include <math.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    using namespace std;
    typedef long long int LL;
    const int maxn=3e5+10;
    char str[maxn];
    struct Tree
    {
        int next[maxn][26];
        int fail[maxn];
        int num[maxn];
        LL cnt[maxn];
        int len[maxn];
        int s[maxn];
        int p;
        int n;
        int last;
        int new_node(int x)
        {
            memset(next[p],0,sizeof(next[p]));
            cnt[p]=0;
            num[p]=0;
            len[p]=x;
            return p++;
        }
        void init()
        {
            p=0;
            new_node(0);
            new_node(-1);
            last=0;n=0;
            s[0]=-1;
            fail[0]=1;
        }
        int get_fail(int x)
        {
            while(s[n-len[x]-1]!=s[n])
                x=fail[x];
            return x;
        }
        int add(int x)
        {
            x-='a';
            s[++n]=x;
            int cur=get_fail(last);
            if(!(last=next[cur][x]))
            {
                int now=new_node(len[cur]+2);
                fail[now]=next[get_fail(fail[cur])][x];
                next[cur][x]=now;
                num[now]=num[fail[now]]+1;
                last=now;
            }
            cnt[last]++;
        }
        void count()
        {
            for(int i=p-1;i>=0;i--)
                cnt[fail[i]]+=cnt[i];
        }
    }tree;
    int main()
    {
        while(scanf("%s",str)!=EOF)
        {
            int len=strlen(str);
            tree.init();
            for(int i=0;i<len;i++)
                tree.add(str[i]);
            tree.count();
            LL ans=0;
            for(int i=2;i<tree.p;i++)
                ans=max(ans,(LL)tree.cnt[i]*tree.len[i]);
            printf("%lld
    ",ans);
        }
        return 0;
    }
    


  • 相关阅读:
    1023. 组个最小数
    1021. 个位数统计
    *1020. 月饼
    *1019. 数字黑洞
    1016. 部分A+B
    *1014. 福尔摩斯的约会
    *1013. 数素数
    *1012. 数字分类
    1011. A+B和C
    *1008. 数组元素循环右移问题
  • 原文地址:https://www.cnblogs.com/dacc123/p/8228636.html
Copyright © 2011-2022 走看看