洛谷 3649 「APIO2014」回文串 发表于 2020.07.18 | 分类于 题解 | 14 学了学 PAM,就不写学习笔记了,因为比较简单。 PAM 模板题,建出 PAM 然后在 Fail 树上统计出现次数即可。 注意到 PAM 的 Fail 树一个拓扑序即为状态建立的顺序。 代码: 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 3e5;int n;char s[N + 5];long long ans;namespace PAM{ struct node { int ch[26]; int fa,len,sz; } pam[N + 5]; int las = 1,tot = 1; inline int init() { pam[1].len = -1,pam[0].fa = 1; return 0; } int Init = init(); void insert(char *s,int i) { int cur = las,x = s[i] - 'a'; for(;s[i - pam[cur].len - 1] ^ s[i];cur = pam[cur].fa); if(!pam[cur].ch[x]) { int p = ++tot,q = pam[cur].fa; pam[p].len = pam[cur].len + 2; for(;s[i - pam[q].len - 1] ^ s[i];q = pam[q].fa); pam[p].fa = pam[q].ch[x],pam[cur].ch[x] = p; } ++pam[las = pam[cur].ch[x]].sz; } inline void build() { for(register int i = tot;i > 2;--i) pam[pam[i].fa].sz += pam[i].sz,ans = max(ans,(long long)pam[i].len * pam[i].sz); }}int main(){ scanf("%s",s + 1),n = strlen(s + 1); for(register int i = 1;i <= n;++i) PAM::insert(s,i); PAM::build(); printf("%lld\n",ans);} 本文作者: Alpha1022 本文链接: https://www.alpha1022.me/articles/lg-3649.htm 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明出处!