您的位置:首页 > 其它

UVAlive 4975 Manacher+枚举

2017-09-20 15:25 267 查看

题意:

题目链接:https://vjudge.net/problem/UVALive-4975

给出一个字符串,求形如XYXY的最长子串长度,其中Y时X的逆字符串。

思路:

一开始没仔细想上来就二分hash,后来发现并不满足二分条件。

正解是manacher预处理,然后暴力枚举长度,枚举时有讲究,显然长度一定时4的倍数,然后再看左右两个子串的回文串范围。

代码:

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

int n, l;
int len[MAXN << 1];
char a[MAXN], s[MAXN];

int manachar (char *p) {
n = strlen (p), l = 0;
s[l++] = '@';
s[l++] = '#';
for (int i = 0; i < n; i++) {
s[l++] = p[i];
s[l++] = '#';
}
s[l++] = '~'; s[l] = 0;
//cout << s << endl;

int Max = 0, pos = 0, ans = 0;
for (int i = 1; i < l; i++) {
if (Max > i) {
len[i] = min (len[2 * pos - i], Max-i);
}
else
len[i] = 1;
while (s[i+len[i]] == s[i-len[i]])
len[i]++;
ans = max (ans, len[i]);
if (len[i] + i > Max) {
Max = len[i]+i;
pos = i;
}
}
return ans-1;
}

int main() {
//freopen("in.txt", "r", stdin);
int T;
scanf("%d", &T);
while (T--) {
scanf("%s", a);
manachar(a);
int ans = 0;
for (int i = 1; i < l; i += 2) {
int x = len[i] - 1;
if (x < 4) continue;
while (x % 4 != 0) x--;
for (; x > ans; x -= 4) {
int p1 = i - x / 2, p2 = i + x / 2;
if (len[p1] - 1 >= x / 2 && len[p2] - 1 >= x / 2) {
ans = x;
break;
}
}
}
printf("%d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: