P3649 [APIO2014]回文串

P3649 [APIO2014]回文串

根据后缀链接,形成的回文树,对于每一个节点,其子树大小(包括该节点)即为该回文串的出现次数。

// Created by CAD
#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int maxn=3e5+5;
namespace pam{
    int sz,tot,last;
    int len[maxn],fail[maxn],cnt[maxn];
    char s[maxn];
    vector<int> Next[maxn];
    int node(int l){
        len[++sz]=l;
        Next[sz].resize(26,0);
        fail[sz]=cnt[sz]=0;
        return sz;
    }
    void init(){
        sz=-1;
        s[tot=0]='$';
        node(0),node(-1);
        fail[0]=1,last=0;
    }
    int getfail(int x){
        while(s[tot-len[x]-1]!=s[tot]) x=fail[x];
        return x;
    }
    void insert(char c){
        s[++tot]=c;
        int now=getfail(last);
        if(!Next[now][c-'a']){
            int id=node(len[now]+2);
            fail[id]=Next[getfail(fail[now])][c-'a'];
            Next[now][c-'a']=id;
        }
        last=Next[now][c-'a'];
        cnt[last]++;
    }
    ll solve(){
        for(int i=sz;i>=0;--i)
            cnt[fail[i]]+=cnt[i];
        ll ans=0;
        for(int i=2;i<=sz;++i)
            ans=max(ans,1ll*cnt[i]*len[i]);
        return ans;
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    string s;cin>>s;
    pam::init();
    for(auto i:s)
        pam::insert(i);
    cout<<pam::solve()<<endl;
    return 0;
}

posted @ 2020-07-29 16:10  caoanda  阅读(113)  评论(0编辑  收藏  举报