USACO Section 1.3 Calf Flac

manacher求最长子串。

/*

PROG : calfflac

LANG : C++

*/



# include <cstdio>

# include <cctype>



# define N 20000 + 5



int n;

char s[N];



int Min(int x, int y)

{

    return x < y ? x : y;

}



int manacher(char *s, int len, int &st)

{

    int n = len*2+1;

    char t[2 * N];



    /*  insert '#' in string s to form a 2*len+1 string t

         在 s 中插入 len+1 个 '#' 使 s 中的奇偶回文字符串统一起来   */

    for (int i = 0; i < len; ++i)

    {

        t[2*i] = '#';

        t[2*i+1] = s[i];

    }

    t[n-1] = '#';



    int ret = 0;

    int p[2 * N];

    int mx = 0, id;

    for (int i = 1; i < n; ++i)

    {

        p[i] = mx>i ? Min(p[2*id-i], mx-i):1;

        while (t[i-p[i]] == t[i+p[i]]) ++p[i];

        if (i+p[i] > mx) mx = i+p[i], id = i;

        /*  find the longest sub-palindrome,

            set ret and st(start position of LSP in s) */

        if (p[i]-1 > ret)

        {

            ret = p[i] - 1;

            st = (i-p[i]+1)/2;

        }

    }

    return ret;

}



void solve(void)

{

    int st;

    int r[N];

    char ss[N];

    int k = 0;

    for (int i = 0; i < n; ++i)

    {

        if (isalpha(s[i]))

        {

            r[k] = i;

            ss[k++] = tolower(s[i]);

        }

    }

    int len = manacher(ss, k, st);

    s[r[st+len-1]+1] = 0;

    printf("%d\n%s\n", len, s+r[st]);

}



int main()

{

    freopen("calfflac.in", "r", stdin);

    freopen("calfflac.out", "w", stdout);



    n = 0;

    while ((s[n++]=getchar()) != EOF) ;



    solve();



    fclose(stdin);

    fclose(stdout);



    return 0;

}

manacher的资料;

Finding the Longest Palindromic Substring in Linear Time

Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串

你可能感兴趣的:(USACO)