模板 - 字符串 - Manacher算法

注意:长度为n的字符串s,下标范围为[0,n-1]。len[i+j]存放所有的[i,j]的共同中心(i+j)/2向左右拓展出的最长长度,注意当i+j为偶数时,中心为一个字符,必有len[i+j]>=1。根据奇偶性也容易知道len[i]表示回文串的实际长度为int l = (len[i] << 1) - (!(i & 1));

易知len的下标范围为[0,2n-2]。

char s[1000005];
int len[2000005];

void manacher(char *s, int *len, int n) {
    len[0] = 1;
    for(int i = 1, j = 0; i < (n << 1) - 1; ++i) {
        int p = i >> 1, q = i - p, r = ((j + 1) >> 1) + len[j] - 1;
        len[i] = r < q ? 0 : min(r - q + 1, len[(j << 1) - i]);
        while(p > len[i] - 1 && q + len[i] < n && s[p - len[i]] == s[q + len[i]])
            ++len[i];
        if(q + len[i] - 1 > r)
            j = i;
    }
}
posted @ 2020-03-23 10:03  KisekiPurin2019  阅读(140)  评论(0编辑  收藏  举报