模板题:https://www.luogu.org/problemnew/show/P3649
知识点:1.回文自动机算法,关键在于理解getfail函数和fail数组(与AC自动机有些相似)
2.初始化。
3.注意cnt的定义,就比如说此题中每个回文串的出现次数不只是cnt[i]。
#include <bits/stdc++.h> using namespace std; char c[1300002]; long long lst,tot; long long ch[300002][30],cnt[300002],len[300002],fail[300002]; void init() { len[0] = 0,len[1] = -1; fail[0] = 1; tot = 1; lst = 0; c[0] = '~'; } long long getfail(long long t,long long x) { while(c[t - len[x] - 1] != c[t])x = fail[x]; return x; } long long newnode(long long t) { len[++tot] = t; return tot; } void insert(long long t) { long long x; x = getfail(t,lst); long long u = c[t] - 'a'; if(!ch[x][u]) { long long h = newnode(len[x] + 2); fail[h] = ch[getfail(t,fail[x])][u];//wrong1:AC:ch[getfail(fail[x],t)][u],WA:ch[getfail(t,fail[x])][u] ch[x][u] = h; } ++cnt[ch[x][u]]; lst = ch[x][u]; } void count() { for(long long i = tot;i > 0;i--) cnt[fail[i]] += cnt[i]; } int main() { scanf("%s",c + 1); init(); long long length = strlen(c + 1); for(long long i = 1;i <= length;i++) { insert(i); } count(); long long ans = -1; for(long long i = tot;i >= 0;i--) { ans = max(ans,cnt[i] * len[i]); } printf("%lld",ans); return 0; }