P4555 [国家集训队]最长双回文串

Posted zgglj-com

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P4555 [国家集训队]最长双回文串相关的知识,希望对你有一定的参考价值。

题意:求这样一个回文串S,S = A + B 且 A, B都是回文串。问最长S

题解:建立两颗回文树,一个从前向后插,一个从后向前插,并记录每个位置得到的最长后缀后文。

ps:马拉车的做法待更

const int N = 100005;

struct data {
    int len, fail;
    int ch[26];
};

struct PldTree {
    int tot, last;
    int cnt[N];

    char s[N];
    data node[N];

    void Inite() {
        tot = last = 1;
        node[0].fail = 1;
        node[1].len = -1;
    }
    void Insert(int i) {
        while(s[i] != s[i - node[last].len - 1]) last = node[last].fail;
        if (!node[last].ch[s[i] - a]) {
            node[++tot].len = node[last].len + 2;
            cnt[i] = node[tot].len;

            int tp = node[last].fail;
            while(s[i] != s[i - node[tp].len - 1]) tp = node[tp].fail;

            node[tot].fail = node[tp].ch[s[i] - a];
            node[last].ch[s[i] - a] = tot;
            last = tot;
        }
        else {
            last = node[last].ch[s[i] - a];
            cnt[i] = node[last].len;
        }
    }
};

PldTree T1, T2;

inline void upd(int &a, int b) {
    (a < b) && (a = b);
}

int main()
{
    T1.Inite();
    T2.Inite();

    T1.s[0] = T2.s[0] = 0;

    scanf("%s", T1.s + 1);

    int n = strlen(T1.s + 1);
    Rep(i, 1, n) {
        T2.s[i] = T1.s[n + 1 - i];
        T1.Insert(i);
    }

    Rep(i, 1, n) {
        T2.Insert(i);
    }

    int ans = 0;
    Rep(i, 1, n) upd(ans, T1.cnt[i] + T2.cnt[n - i]);

    pr(ans);
    return 0;
}

 

以上是关于P4555 [国家集训队]最长双回文串的主要内容,如果未能解决你的问题,请参考以下文章

P4555 [国家集训队]最长双回文串(回文树)

P4555 [国家集训队]最长双回文串

P4555 最长双回文串

[国家集训队]最长双回文串

备战省选

最长双回文串