ACM模版——Manacher(最长回文子串)算法

注释版:

#include
#include

#define mem(a,b) memset(a,b,sizeof a)
#define INF 0x3f3f3f3f

using namespace std;

typedef long long ll;

const int maxn=100100;
char a[maxn*2]; // $ # s[]
int b[maxn*2]; // RL[]

// 时间复杂度 O(n)
int manacher(char s[])
{
    int rs=-1;
    int len=strlen(s);
    int k=0;
    a[k++]='$';
    a[k++]='#';
    for(int i=0;i $#a#b#b#a#'\0' (从0开始)

    // 表示当前访问到的所有回文子串,所能触及的最右一个字符的位置+1(即:最右边一个回文字符串的下一个位置)
    // mxr 对应的回文串的对称轴所在的位置,记为pos
    int mxr=0,pos=0;
    for(int i=0;ii?min(b[2*pos-i],mxr-i):1;

        while(a[i+b[i]]==a[i-b[i]]) // 无需处理边界问题,因为我们一开始预处理 $、'\0'
            b[i]++;

        if(i+b[i]>mxr) // 不论以上哪种情况,之后都要尝试更新 mxr 和 pos,因为有可能得到更大的 mxr。
            mxr=i+b[i],pos=i;

        rs=max(rs,b[i]-1); // 更新最长回文串的长度
    }

    return rs;
}

int main()
{
    char s[maxn];
    while(gets(s))
    {
        printf("%d\n",manacher(s));
    }

    return 0;
}


简化版:

#include
#include

#define mem(a,b) memset(a,b,sizeof a)
#define INF 0x3f3f3f3f

using namespace std;

typedef long long ll;

const int maxn=100100;
char a[maxn*2];
int b[maxn*2];

int manacher(char s[])
{
    int rs=-1;
    int len=strlen(s);
    int k=0;
    a[k++]='$';
    a[k++]='#';
    for(int i=0;ii?min(b[2*pos-i],mxr-i):1;

        while(a[i+b[i]]==a[i-b[i]])
            b[i]++;

        if(i+b[i]>mxr)
            mxr=i+b[i],pos=i;

        rs=max(rs,b[i]-1);
    }

    return rs;
}

int main()
{
    char s[maxn];
    while(gets(s))
    {
        printf("%d\n",manacher(s));
    }

    return 0;
}

你可能感兴趣的:(#,ACM,#,串,#,ACM,模板)