您的位置:首页 > 其它

字符串模拟赛T2

2016-07-20 19:25 288 查看




// source code from laekov for c0x17
#define PRID "fkqh"
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn = 200009;

int n, l[maxn], q[maxn], vx[maxn], vy[maxn];
char a[maxn];

void manacher() {
l[0] = 1;
for (int i = 1, j = 0; i < (n << 1) - 1; ++ i) {
int r = ((j + 1) >> 1) + l[j] - 1;
int p = i >> 1, q = i - p;
l[i] = (r >= q) ? min(r - q + 1, l[(j << 1) - i]) : 0;
while (p - l[i] >= 0 && q + l[i] < n && a[p - l[i]] == a[q + l[i]])
++ l[i];
if (q + l[i] - 1 > 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 = 0, tl = 0;
if (!d) {
for (int i = 0; i < n; ++ i) {
if (!tl || getRight(i << 1) > getRight(q[tl - 1]))
q[tl ++] = (i << 1);
while (getRight(q[hd]) < i)
++ hd;
vx[i] = (i << 1) - q[hd] + 1;
if (i < n - 1 && getRight((i << 1) + 1) > getRight(q[tl - 1]))
q[tl ++] = (i << 1) + 1;
}
}
else {
for (int i = n - 1; i >= 0; -- i) {
if (!tl || getLeft(i << 1) < getLeft(q[tl - 1]))
q[tl ++] = (i << 1);
while (getLeft(q[hd]) > i)
++ hd;
vy[i] = q[hd] - (i << 1) + 1;
if (i && getLeft((i << 1) -1) < getLeft(q[tl - 1]))
q[tl ++] = (i << 1) - 1;
}
}
}

int main(int argc, char* args[]) {
if (argc < 2 || strcmp(args[1], "-nf")) {
freopen(PRID ".in", "r", stdin);
freopen(PRID ".out", "w", stdout);
}
scanf("%s", a);
n = strlen(a);
manacher();
dp(0);
dp(1);
int ans = 2;
for (int i = 1; i < n; ++ i)
ans = max(ans, vx[i - 1] + vy[i]);
printf("%d\n", ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: