存在其中一个最长双倍回文子串是以某个位置为开始的最长回文子串。
瞎猜的结论,居然能过(
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <set>
#include <vector>
const int maxn = 500000 + 10;
char a[maxn], s[2 * maxn];
int d[2 * maxn];
std::vector<int> v[maxn];
int r[maxn];
int main()
{
int n;
scanf("%d %s", &n, a + 1);
for (int i = 1; i <= 2 * n + 1; i++) s[i] = i & 1 ? '#' : a[i / 2];
for (int i = 1, l = 0, r = 0; i <= 2 * n + 1; i++)
{
d[i] = 0;
if (i <= r) d[i] = std::min(d[2 * l - i], r - i + 1);
while (d[i] <= std::min(i - 1, 2 * n + 1 - i) && s[i + d[i]] == s[i - d[i]]) d[i]++;
if (i + d[i] - 1 > r) l = i, r = i + d[i] - 1;
}
for (int i = 1; i <= 2 * n + 1; i += 2)
{
if ((i - d[i]) / 2 + 1 > (i - 1) / 2) continue;
v[(i - d[i]) / 2 + 1].push_back((i - 1) / 2);
v[(i - 1) / 2 + 1].push_back(-(i - 1) / 2);
}
int ans = 0;
std::multiset<int> set;
for (int i = 1; i <= n; i++)
{
for (int j : v[i])
{
if (j >= 0) set.insert(j);
else set.erase(set.find(-j));
}
if (set.empty()) continue;
r[i] = 2 * *set.rbegin() - i + 1;
if ((r[i] - i + 1) % 4 == 0)
{
int t = (r[i] - i + 1) / 4;
if (d[(i + t - 1) * 2 + 1] - 1 >= 2 * t && d[(i + 3 * t - 1) * 2 + 1] - 1 >= 2 * t) ans = std::max(ans, r[i] - i + 1);
}
}
printf("%d", ans);
return 0;
}