本来想严谨细致地写一篇介绍…
然而已经有神犇写过详细论文了
于是就丢链接跑好了
http://victorwonder.blog.uoj.ac/blog/146
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <algorithm> #include <string.h> #include <vector> #include <math.h> #include <limits> #include <set> #include <map> using namespace std; struct PTree { #define SZ 666666 int ch[SZ][26],len[SZ],fail[SZ],cnt[SZ],s[SZ],cl,an,lst; int addn(int l) {len[an]=l; return an++;} PTree() { cl=an=lst=0; memset(ch,0,sizeof(ch)); addn(0); addn(-1); fail[0]=1; s[0]=-233; } int gfail(int x,int l) { while(s[l-len[x]-1]!=s[l]) x=fail[x]; return x; } void add(int c) { s[++cl]=c; int cp=gfail(lst,cl); if(!ch[cp][c]) { int nn=addn(len[cp]+2); fail[nn]=ch[gfail(fail[cp],cl)][c]; ch[cp][c]=nn; } cnt[lst=ch[cp][c]]++; } void getcnt() { for(int i=an-1;i>=2;i--) cnt[fail[i]]+=cnt[i]; } }pt; char s[SZ]; int main() { scanf("%s",s); for(int i=0;s[i];i++) pt.add(s[i]-'a'); pt.getcnt(); long long ans=0; for(int i=2;i<=pt.an;i++) ans=max(ans,pt.len[i]*(long long)pt.cnt[i]); printf("%lld ",ans); }