BZOJ2565 最长双回文串(回文树)

来源:互联网 发布:sql文件太大打不开 编辑:程序博客网 时间:2024/05/17 04:48

HYSBZ - 2565

最长双回文串
Time Limit: 10000MS Memory Limit: 131072KB 64bit IO Format: %lld & %llu

Submit Status

Description

顺序和逆序读起来完全一样的串叫做回文串。比如acbca是回文串,而abc不是(abc的顺序为“abc”,逆序为“cba”,不相同)。
输入长度为n的串S,求S的最长双回文子串T,即可将T分为两部分XY,(|X|,|Y|≥1)且XY都是回文串。

Input

一行由小写英文字母组成的字符串S

Output

一行一个整数,表示最长双回文子串的长度。

Sample Input

baacaabbacabb

Sample Output

12

Hint

样例说明

从第二个字符开始的字符串aacaabbacabb可分为aacaa与bbacabb两部分,且两者都是回文串。

对于100%的数据,2≤|S|≤10^5


2015.4.25新加数据一组

Source

Submit Status



倒着顺着来一遍

#include <bits/stdc++.h>using namespace std;const int MAXN = 1e5 + 10;#define N 26struct Palindromic_Tree {    int next[MAXN][N];    int fail[MAXN], cnt[MAXN], len[MAXN],num[MAXN],S[MAXN];    int n,p,last;    int newnode(int l)    {        for(int i = 0; i < N; ++i) next[p][i] = 0;        cnt[p] = 0;        num[p] = 0;        len[p] = l;        return p++;    }    void init()    {        last = n = p = 0;        newnode(0);        newnode(-1);        S[0] = -1;        fail[0] = 1;        fail[1] = 0;    }    int get_fail(int x)    {        while(S[n-len[x]-1] != S[n]) x = fail[x];        return x;    }    int add(int c) ///返回新添加的节点    {        c -= 'a';        S[++n] = c;        int cur = get_fail(last);        if(!next[cur][c]) {            int now = newnode(len[cur]+2);            fail[now] = next[get_fail(fail[cur])][c];            next[cur][c] = now;            num[now] = num[fail[now]] + 1;        }        last = next[cur][c];        ++cnt[last];        return last;    }    void count()    {        for(int i = p-1; i >= 0; --i) cnt[fail[i]] += cnt[i];    }};Palindromic_Tree T;int len[MAXN];char s[MAXN];int main(){    while(scanf("%s",s+1)==1) {        T.init();        int n = strlen(s+1);        for(int i = n; i >= 1; --i)len[i] = T.len[T.add(s[i])];        int ans = 0;        T.init();        for(int i = 1; i < n; ++i) ans = max(ans,len[i+1]+T.len[T.add(s[i])]);        printf("%d\n",ans);    }    return 0;}




0 0