洛谷 4555 最长双回文串 发表于 2020.07.18 | 分类于 题解 | 9 对正串反串分别建 PAM,求出以每个位置为结尾 / 开头的最长回文子串即可。 代码: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 1e5;int n;char s[N + 5],t[N + 5];int l[N + 5],r[N + 5],ans;namespace PAM1{ struct node { int ch[26]; int fa,len; } 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; } las = pam[cur].ch[x]; }}namespace PAM2{ struct node { int ch[26]; int fa,len; } 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; } las = pam[cur].ch[x]; }}int main(){ scanf("%s",s + 1),n = strlen(s + 1); for(register int i = 1;i <= n;++i) PAM1::insert(s,i),t[i] = s[n - i + 1],l[i] = PAM1::pam[PAM1::las].len; for(register int i = 1;i <= n;++i) PAM2::insert(t,i),r[n - i + 1] = PAM2::pam[PAM2::las].len; for(register int i = 1;i < n;++i) ans = max(ans,l[i] + r[i + 1]); printf("%d\n",ans);} 本文作者: Alpha1022 本文链接: https://www.alpha1022.me/articles/lg-4555.htm 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明出处!