• P3649 [APIO2014]回文串


    题目描述

    给你一个由小写拉丁字母组成的字符串 ss。我们定义 ss 的一个子串的存在值为这个子串在 ss 中出现的次数乘以这个子串的长度。

    对于给你的这个字符串 ss,求所有回文子串中的最大存在值。

    输入输出格式

    输入格式:

     

    一行,一个由小写拉丁字母(a~z)组成的非空字符串 ss。

     

    输出格式:

     

    输出一个整数,表示所有回文子串中的最大存在值。

     

    输入输出样例

    输入样例#1: 复制
    abacaba
    
    输出样例#1: 复制
    7
    
    输入样例#2: 复制
    www
    输出样例#2: 复制
    4

    说明

    【样例解释1】

    用 lvert s verts∣ 表示字符串 ss 的长度。

    一个字符串 s_1 s_2 dots s_{lvert s vert}s1s2ss 的子串是一个非空字符串 s_i s_{i+1} dots s_jsisi+1sj,其中 1 leq i leq j leq lvert s vert1ijs∣。每个字符串都是自己的子串。

    一个字符串被称作回文串当且仅当这个字符串从左往右读和从右往左读都是相同的。

    这个样例中,有 77 个回文子串 a,b,c,aba,aca,bacab,abacaba。他们的存在值分别为 4, 2, 1, 6, 3, 5, 74,2,1,6,3,5,7。

    所以回文子串中最大的存在值为 77。

    第一个子任务共 8 分,满足 1 leq lvert s vert leq 1001s100。

    第二个子任务共 15 分,满足 1 leq lvert s vert leq 10001s1000。

    第三个子任务共 24 分,满足 1 leq lvert s vert leq 100001s10000。

    第四个子任务共 26 分,满足 1 leq lvert s vert leq 1000001s100000。

    第五个子任务共 27 分,满足 1 leq lvert s vert leq 3000001s300000。

     



     

    首先可以SA+manacher,但是这是回文树的板子(-。-)



     1 #include"bits/stdc++.h"
     2 using namespace std;
     3 typedef long long ll;
     4 const int nn = 300010;
     5 
     6 char s[300010];
     7 
     8 int fail[nn],len[nn],cnt[nn];
     9 int nxt[nn][26];
    10 int S[nn];
    11 int tot;
    12 int num=1;
    13 inline int getfail(int x){
    14     for (;S[tot-len[x]-1]!=S[tot];x=fail[x]); return x;
    15 }
    16 
    17 int main()
    18 {
    19     scanf("%s",s);  int last;
    20     int n=strlen(s);   
    21     fail[0]=1;len[1]=-1;last=0;tot=0; S[0]=-1;
    22     for (register int i=0;i<n;i++)
    23     {
    24     //    cout<<i<<endl;
    25         int c=s[i]-'a'; S[++tot]=c;int cur=getfail(last);
    26     //    cout<<123<<endl;
    27         if (!nxt[cur][c])
    28         {   
    29             fail[++num]=nxt[getfail(fail[cur])][c];//顺序
    30             nxt[cur][c]=num;
    31             len[num]=len[cur]+2;
    32             
    33         //    cout<<123<<endl;; 
    34         }
    35          last=nxt[cur][c]; cnt[last]++;
    36     }
    37     ll ans=0;
    38     
    39     for (register int i=num;i>=2;i--)cnt[fail[i]]+=cnt[i];
    40     for (register int i=num;i>=2;i--)
    41     {
    42         ans=max(ans,1ll*cnt[i]*len[i]);
    43     }
    44     
    45     printf("%lld",ans);
    46  } 
  • 相关阅读:
    c++11——列表初始化
    flask学习(十二):for循环遍历
    flask学习(十一):if判断语句
    flask学习(十):模板中访问模型和字典的属性
    flask学习(九):模板渲染和参数传递
    flask学习(八):页面跳转和重定向
    flask学习(七):URL反转
    flask学习(六):URL传参
    flask学习(五):使用配置文件
    flask学习(四):debug模式
  • 原文地址:https://www.cnblogs.com/zhangbuang/p/10332998.html
Copyright © 2020-2023  润新知