题意:计算w wR w wR的最大长度
题解:构建出回文自动机,在fail树中dfs一遍即可。
时间复杂度:
O(n)
空间复杂度:
O(26n)
代码:
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cstdio>
using namespace std;
char s[501000];
int head[501000],ver[501000],nextt[501000],tot;
void add(int x,int y)
{
tot++;
nextt[tot]=head[x];
head[x]=tot;
ver[tot]=y;
}
int n;
struct data
{
int len[501000],next[501000][26];
int fail[501000],cnt,num[501000],last,tot;
data()
{
len[0] = 0;len[1] = -1;fail[0] = 1;
last = 0;cnt = 1;
}
void insert()
{
int l = n;
for (int i = 1;i <= l;i++)
{
int t = s[i] - 'a';
while (s[i - len[last] - 1] != s[i]) last = fail[last];
if (!next[last][t])
{
cnt++;len[cnt] = len[last] + 2;
int cur = fail[last];
while (s[i-len[cur]-1]!=s[i]) cur = fail[cur];
cur = next[cur][t];
fail[cnt] = cur;
next[last][t] = cnt;
}
last = next[last][t];
num[last]++;
}
}
void failtree()
{
add(1,0);
for (int i = 2;i <= cnt;i++) add(fail[i],i);
}
}par;
int num[501000],ans;
void dfs(int x)
{
if (par.len[x] != -1)num[par.len[x]]++;
if (par.len[x]%4==0 && num[par.len[x]/2]) ans = max(ans,par.len[x]);
for (int i = head[x];i!=-1;i=nextt[i])
dfs(ver[i]);
if (par.len[x] != -1)num[par.len[x]]--;
}
int main()
{
int l;
cin >> n;
scanf("%s",s+1);
s[0] = -1;
par.insert();
memset(head,-1,sizeof head);
par.failtree();
dfs(1);
cout << ans <<endl;
}