P3649 [APIO2014]回文串

ps:针对 fail 链出的题,一个点的fail指向的节点一定是这个点的子串。

const int N = 300005;

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

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

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

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

    void Inite() {
        mem(res, 0);
        tot = last = 1;
        node[1].len = -1;
        node[0].fail = 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;

            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 = node[last].ch[s[i] - 'a'];
        res[last]++;
    }
    LL get() {
        LL ans = 0;
        for (int i = tot; i > 1; --i) {
            res[node[i].fail] += res[i];
            upd(ans, 1ll * res[i] * node[i].len);
        }
        return ans;
    }
};

PldTree T;

int main()
{
    T.Inite();
    scanf("%s", T.s + 1);

    int n = strlen(T.s + 1);
    Rep(i, 1, n) T.Insert(i);

    pr(T.get());
    return 0;
}
原文地址:https://www.cnblogs.com/zgglj-com/p/9610193.html