Aizu2292 Common Palindromes

Posted cjoieryl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Aizu2292 Common Palindromes相关的知识,希望对你有一定的参考价值。

题意

我也不知道哪里来的OJ (vjudge) 上的
给定两个字符串 (S,T) ,询问 ((i,j,k,l)) 这样的四元组个数
使得 (S[i,j],T[k,l]) 是相等的回文串

Sol

回文树
记录 (S) 的每个回文串的出现位置的集合大小
匹配 (T) 记录其每个回文串出现的位置集合大小
相乘即可

# include <bits/stdc++.h>
# define IL inline
# define RG register
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;

IL int Input(){
    RG int x = 0, z = 1; RG char c = getchar();
    for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
    for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
    return x * z;
}

const int maxn(5e4 + 5);

int son[26][maxn], len[maxn], num[maxn], fa[maxn], vis[maxn];
int tot, n, last;
char s[maxn], t[maxn];

IL void Extend(RG int pos, RG int c){
    RG int p = last;
    while(s[pos - len[p] - 1] != s[pos]) p = fa[p];
    if(!son[c][p]){
        RG int np = ++tot, q = fa[p];
        while(s[pos - len[q] - 1] != s[pos]) q = fa[q];
        len[np] = len[p] + 2, fa[np] = son[c][q];
        son[c][p] = np;
    }
    last = son[c][p], ++num[last];
}

int main(){
    scanf(" %s %s", s + 1, t + 1), n = strlen(s + 1);
    fa[0] = fa[1] = tot = 1, len[1] = -1;
    for(RG int i = 1; i <= n; ++i) Extend(i, s[i] - 'A');
    n = strlen(t + 1);
    for(RG int i = 1, nw = 1; i <= n; ++i){
        RG int c = t[i] - 'A';
        while(nw != 1 && (!son[c][nw] || t[i - len[nw] - 1] != t[i])) nw = fa[nw];
        if(son[c][nw] && t[i - len[nw] - 1] == t[i]) nw = son[c][nw];
        ++vis[nw];
    }
    for(RG int i = tot; i; --i) num[fa[i]] += num[i], vis[fa[i]] += vis[i];
    RG ll ans = 0;
    for(RG int i = 2; i <= tot; ++i) ans += 1LL * num[i] * vis[i];
    printf("%lld
", ans);
    return 0;
}

以上是关于Aizu2292 Common Palindromes的主要内容,如果未能解决你的问题,请参考以下文章

ZOJ 1078 Palindrom Numbers

Aizu 2249 & cf 449B

Aizu - 0121

Aizu-Insertion Sort

Aizu - 2249

Save your cat Aizu - 2224