【BZOJ 2565】 最长双回文串

【题目链接】

            https://www.lydsy.com/JudgeOnline/problem.php?id=2565

【算法】

           Manacher

【代码】

          

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 10;

char s[MAXN];

inline void Manacher()
{
        int i,pos = 0,mx = 0,len,ans = 0;
        static char tmp[MAXN<<1];
        static int p[MAXN<<1],l[MAXN<<1],r[MAXN<<1];
        len = strlen(s+1);
        for (i = 1; i <= len; i++)
        {
                tmp[2*i-1] = '#';
                tmp[2*i] = s[i];
        }
        tmp[len = 2 * len + 1] = '#';
        for (i = 1; i <= len; i++)
        {
                if (mx > i) p[i] = min(p[2*pos-i],mx-i);
                else p[i] = 1;
                while (i - p[i] >= 1 && i + p[i] <= len && tmp[i-p[i]] == tmp[i+p[i]]) p[i]++;
                if (i + p[i] - 1 > mx)
                {
                        mx = i + p[i] - 1;
                        pos = i;        
                }        
        }        
        pos = 1;
        for (i = 1; i <= len; i++)
        {
                if (tmp[i] == '#')
                {
                        while (pos + p[pos] < i) pos++;
                        l[i] = i - pos;
                }
        }
        pos = len;
        for (i = len; i >= 1; i--)
        {
                if (tmp[i] == '#')
                {
                        while (pos - p[pos] > i) pos--;
                        r[i] = pos - i;
                }
        }
        for (i = 1; i <= len; i++) ans = max(ans,l[i]+r[i]);
        printf("%d\n",ans);
}

int main() 
{
        
        scanf("%s",s+1);
        Manacher();
        
        return 0;
    
}

 

posted @ 2018-07-01 10:41  evenbao  阅读(107)  评论(0编辑  收藏  举报