zoukankan      html  css  js  c++  java
  • [APIO2014]回文串(回文自动机)

    题意

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

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

    |S|<=300000

    题解

    裸的回文树,我们在每一个节点结束的最长回文后缀上记录一个cnt代表出现次数。

    这个最长回文后缀T的每一个回文后缀一定也会出现和cnt[T]一样的次数。

    所以倒着统计答案并使cht前移就行了。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<cstdio>
     5 #include<algorithm>
     6 using namespace std;
     7 const int N=300010;
     8 int n,tot,len[N],fail[N],s[N],last,to[N][30],cnt[N];
     9 int L;
    10 long long ans;
    11 char ch[N];
    12 void init(){
    13     n=0;tot=1;
    14     len[0]=0;len[1]=-1;
    15     fail[0]=1;s[0]=-1;last=0;
    16     memset(to,0,sizeof(to));
    17 }
    18 void add(int c){
    19     s[++n]=c;
    20     int cur,now,tmp;
    21     for(cur=last;s[n-len[cur]-1]!=c;cur=fail[cur]);
    22     if(!to[cur][c]){
    23         tot++;
    24         len[tot]=len[cur]+2;now=tot;
    25         for(tmp=fail[cur];s[n-len[tmp]-1]!=c;tmp=fail[tmp]);
    26         fail[now]=to[tmp][c];
    27         to[cur][c]=now;
    28     } 
    29     last=to[cur][c];
    30     cnt[last]++;
    31 }
    32 void count(){
    33     for(int i=tot;i>=1;i--){
    34         cnt[fail[i]]+=cnt[i];
    35         ans=max(1ll*cnt[i]*len[i],ans);
    36     }
    37 }
    38 int main(){
    39     scanf("%s",ch+1);
    40     L=strlen(ch+1);
    41     init();
    42     for(int i=1;i<=L;i++)add(ch[i]-'a');
    43     count();
    44     printf("%lld",ans);
    45     return 0;
    46 } 
  • 相关阅读:
    kafka参数设置
    安装kafka多节点
    zookeeper集群搭建
    ubuntu安装spark
    ubuntu安装Scala
    elasticsearch添加访问密码
    springcloud整合分布式事务LCN
    springboot分布式事务
    K近邻(KNN)
    最大期望算法(EM算法)
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9554329.html
Copyright © 2011-2022 走看看