Palindrome Centers Manacher算法

来源:互联网 发布:apache ant windows 编辑:程序博客网 时间:2024/05/18 09:20

题目大意

一个长度为n的字符串S, 告诉你以每个位置结尾的最长回文串长度, 要你输出以每个字符为中心的最长长度

思路

开始的时候以为是水题, 以为用题目给的回文串长度, 找到中心, 更新长度就好了, 但这样是错的, 因为如果以j为结尾的回文串中心是i, 以i为中心的最长回文串不一定是只到j, 后面号可能有一个大于j的k, 以i为中心, k为边界也是回文串, 但是以k结尾还可能有一个更长的回文串, 长度为偶数, 这样求出的以i为中心的回文串就不是以k而是以j为边界, 不是最长的了
所以要利用Manacher算法的原理, 同样, 我们在原字符串每个字符两边放一个特殊字符, 将奇偶长度的字符串都转换成奇数长度
设p[i]为新字符串以i为中心的回文串右侧长度+1(包括中心)
题解是这么说的

Let’s say the longest palindrome centered at i from those that can be deduced from the input ends at j. There’s only one situation when this is not the answer: if there is another palindrome that ends at k (j < k) and is centered at i, but the input palindrome ending at k is even longer. But in this case the palindrome ending at k will be centered at an index smaller than ii, so Manacher’s algorithm will identify it before getting at i.

代码

Score: 100/100 (23 ms - 2076 KB)

#include <bits/stdc++.h>using namespace std;const int MAXN = 1e5 + 100;int n, a[MAXN], p[MAXN*2], r;int main(){    ios_base :: sync_with_stdio(0), cin.tie(0), cout.tie(0);    cin >> n;    for(int i=0; i<n; ++i)    {        cin >> a[i];        r = i*2+1;        p[r-a[i]+1] = max(p[r-a[i]+1], a[i]);    }    int id = 0, mx = 0;    for(int i=1; i<2*n; ++i)    {        p[i] = max(p[i],                    mx>i ? min(p[2*id-i], mx-i) : 1);        if(i+p[i]>mx)        {            mx = i+p[i];            id = i;        }    }    for(int i=1; i<2*n; i+=2) cout << p[i] << ' '; cout << endl;    return 0;}
原创粉丝点击