洛谷 5685 「JSOI2013」快乐的 JYY 发表于 2020.08.12 | 分类于 题解 | 11 广义 PAM 板题吧…… 算每个状态在两个字符串分别的出现次数就完事了( 代码: 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 5e4;int n;char s[N + 5];long long ans;namespace PAM{ struct node { int ch[26]; int fa,len,sz[2]; } 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 pos) { 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[pos]; } inline void build() { for(register int i = tot;i > 1;--i) pam[pam[i].fa].sz[0] += pam[i].sz[0], pam[pam[i].fa].sz[1] += pam[i].sz[1], ans += (long long)pam[i].sz[0] * pam[i].sz[1]; }}int main(){ scanf("%s",s + 1),n = strlen(s + 1); for(register int i = 1;i <= n;++i) PAM::insert(s,i,0); PAM::las = 1; scanf("%s",s + 1),n = strlen(s + 1); for(register int i = 1;i <= n;++i) PAM::insert(s,i,1); PAM::build(); printf("%lld\n",ans);} 本文作者: Alpha1022 本文链接: https://www.alpha1022.me/articles/lg-5685.htm 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明出处!