zoukankan      html  css  js  c++  java
  • BZOJ 3676 [Apio2014]回文串(回文树)

    【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=3676

    【题目大意】

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

    【题解】

      我们对给出串建立回文树,统计每个回文串出现次数和长度,相乘取组大即可 

    【代码】

    #include <cstdio>
    #include <algorithm>
    #include <cstring> 
    using namespace std;
    const int N=300010,S=26;
    int all,son[N][S],fail[N],cnt[N],len[N],text[N],last,tot;
    int newnode(int l){
        for(int i=0;i<S;i++)son[tot][i]=0;
        cnt[tot]=0,len[tot]=l;
        return tot++;
    }
    void init(){
        last=tot=all=0;
        newnode(0),newnode(-1);
        text[0]=-1,fail[0]=1;
    }
    int getfail(int x){
        while(text[all-len[x]-1]!=text[all])x=fail[x];
        return x;
    }
    void add(int w){
        text[++all]=w;
        int x=getfail(last);
        if(!son[x][w]){
            int y=newnode(len[x]+2);
            fail[y]=son[getfail(fail[x])][w];
            son[x][w]=y;
        }cnt[last=son[x][w]]++;
    }
    void count(){for(int i=tot-1;~i;i--)cnt[fail[i]]+=cnt[i];}
    char s[N];
    int main(){
        while(~scanf("%s",s)){
            int n=strlen(s); 
            init();
            for(int i=0;i<n;i++)add(s[i]-'a');
            count(); long long ans=0;
            for(int i=0;i<tot;i++)ans=max(ans,1LL*cnt[i]*len[i]);
            printf("%lld
    ",ans);
        }return 0;
    }
  • 相关阅读:
    @override报错
    idea快捷键
    java中getAttribute与getParameter的区别
    localStorage基于浏览器的本地存储
    js画布组件(<canvas></canvas>)
    easyui
    关于Bootstrap
    使用layUI美化的登录功能
    EXT JS
    ★一些文章链接
  • 原文地址:https://www.cnblogs.com/forever97/p/bzoj3676.html
Copyright © 2011-2022 走看看