字符串模拟赛T2

时间:2025-01-01 17:03:56

字符串模拟赛T2

字符串模拟赛T2

// source code from laekov for c0x17
#define PRID "fkqh"
#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; const int maxn = ; int n, l[maxn], q[maxn], vx[maxn], vy[maxn];
char a[maxn]; void manacher() {
l[] = ;
for (int i = , j = ; i < (n << ) - ; ++ i) {
int r = ((j + ) >> ) + l[j] - ;
int p = i >> , q = i - p;
l[i] = (r >= q) ? min(r - q + , l[(j << ) - i]) : ;
while (p - l[i] >= && q + l[i] < n && a[p - l[i]] == a[q + l[i]])
++ l[i];
if (q + l[i] - > r)
j = i;
}
} #define getLeft(x) (((x)>>1)-l[x]+1)
#define getRight(x) ((((x)+1)>>1)+l[x]-1) void dp(bool d) {
static int q[maxn];
int hd = , tl = ;
if (!d) {
for (int i = ; i < n; ++ i) {
if (!tl || getRight(i << ) > getRight(q[tl - ]))
q[tl ++] = (i << );
while (getRight(q[hd]) < i)
++ hd;
vx[i] = (i << ) - q[hd] + ;
if (i < n - && getRight((i << ) + ) > getRight(q[tl - ]))
q[tl ++] = (i << ) + ;
}
}
else {
for (int i = n - ; i >= ; -- i) {
if (!tl || getLeft(i << ) < getLeft(q[tl - ]))
q[tl ++] = (i << );
while (getLeft(q[hd]) > i)
++ hd;
vy[i] = q[hd] - (i << ) + ;
if (i && getLeft((i << ) -) < getLeft(q[tl - ]))
q[tl ++] = (i << ) - ;
}
}
} int main(int argc, char* args[]) {
if (argc < || strcmp(args[], "-nf")) {
freopen(PRID ".in", "r", stdin);
freopen(PRID ".out", "w", stdout);
}
scanf("%s", a);
n = strlen(a);
manacher();
dp();
dp();
int ans = ;
for (int i = ; i < n; ++ i)
ans = max(ans, vx[i - ] + vy[i]);
printf("%d\n", ans);
}