裸Manacher算法题,开一个rank[i]记录映射关系。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cctype>
#include<algorithm>
#include<iterator>
const int maxn = 20000 + 10;
using namespace std;
char s[maxn], in[maxn];
int rank[maxn], p[maxn], id, mx;
bool check(char t) {
if(t >= 'a'&& t <='z'||t >= 'A'&&t <= 'Z') return true;
else return false;
}
int main() {
string src, dst;
for(int i = 0; ; i++) {
scanf("%c", &in[i]);
if(in[i] == EOF) break;
}
src = in;
transform(src.begin(), src.end(), back_inserter(dst), ::toupper);
transform(src.begin(), src.end(), dst.begin(), ::tolower);
int len = 0;
for(int i = 0; i < dst.length(); i++) {
if(check(dst[i])) { s[len] = dst[i]; rank[len] = i; len++;}
}
len *= 2;
for(int i = len; i >= 0; i--) {
if(i & 1) s[i] = s[i / 2];
else s[i] = '#';
}
int pmax = 0;
for(int i = 0; i <= len; i++) {
if(i >= mx) p[i] = 1;
else p[i] = min(mx - i + 1, p[2 * id - i]);
while(i - p[i] >= 0 && i + p[i] <= len && s[i + p[i]] == s[i - p[i]]) p[i]++;
if(i + p[i] - 1 >= mx) {
mx = i + p[i] - 1;
id = i;
}
pmax = max(pmax, p[i]);
}
int k;
for(k = 0; k < len; k++) {
if(p[k] == pmax) break;
}
int l = k - (p[k] - 1); int r = k + (p[k] - 1); r--;
l /= 2, r /= 2;
l = rank[l];
r = rank[r];
cout << pmax - 1 << endl;
for(int i = l; i <= r; i++) cout << src[i];
return 0;
}