#迴文自動機#洛谷 3649 JZOJ 3654 迴文串

題目

給你一個由小寫拉丁字母組成的字符串ss。我們定義ss的一個子串的存在值爲這個子串在ss中出現的次數乘以這個子串的長度。對於給你的這個字符串ss,求所有迴文子串中的最大存在值。


分析

迴文自動機模板,不解釋


代碼

#include <cstdio>
#include <cstring>
#define rr register
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
const int N=300011; char s[N]; int length,n; long long ans;
struct Trie{int trie[27],fail,len,s;};
struct PAM{
    Trie h[N]; int lst,cnt;
    inline void init(){h[0].len=h[1].fail=lst=0,h[0].fail=cnt=1,h[1].len=-1;}
    inline signed gail(int now){for (;s[n-h[now].len-1]^s[n];now=h[now].fail); return now;}
    inline void Insert(){
        rr int now=gail(lst);
        if (!h[now].trie[s[n]^96]){
            h[++cnt].len=h[now].len+2;
            rr int t=gail(h[now].fail);
            h[cnt].fail=h[t].trie[s[n]^96];
            h[now].trie[s[n]^96]=cnt;
        }
        lst=h[now].trie[s[n]^96];
        ++h[lst].s;
    }
}pam;
inline void print(int ans){
	if (ans>9) print(ans/10);
	putchar(ans%10+48);
}
signed main(){
    scanf("%s",s+1),length=strlen(s+1);
    s[0]=96,pam.init();
    for (n=1;n<=length;++n) pam.Insert();
    for (rr int i=pam.cnt;i;--i){
    	pam.h[pam.h[i].fail].s+=pam.h[i].s;
    	ans=max(ans,1ll*pam.h[i].s*pam.h[i].len);
    }
    return !printf("%lld",ans);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章