题目链接
发现博客里没有回文树的板子
所以写一道**题来补一下(话说我之前都没补吗
被学长嘲讽博客里都是模板(我的博客就是用来存模板的ya hahahahahhaa
这题就是瞎搞
不用想太多直接瞎搞
回文树建出来
问题就转化成对于
每个长度为4的倍数、且fail树上存在一个父亲的长度为自身长度的一半的节点的长度最大值
就是这样了,dfs一下就好
代码:
#include<cstdio>
#include<vector>
#include<queue>
#include<ctime>
#include<algorithm>
#include<cstdlib>
#include<stack>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long LL;
const int INF = 2147483647;
const int maxn = 500010;
char s[maxn];
vector<int> e[maxn];
int n,ans,tot,now,last,cnt[maxn];
int fa[maxn],len[maxn],ch[maxn][30];
inline LL getint()
{
LL ret = 0,f = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9') ret = ret * 10 + c - '0',c = getchar();
return ret * f;
}
inline int getfail(int x)
{
while (s[now] != s[now - len[x] - 1]) x = fa[x];
return x;
}
inline void init()
{
len[tot = 1] = -1;
len[last = 0] = 0;
fa[0] = 1;
s[0] = '%';
}
inline void add(int x)
{
int cur = getfail(last);
if (!ch[cur][x])
{
int p = ++tot;
len[p] = len[cur] + 2;
fa[p] = ch[getfail(fa[cur])][x];
ch[cur][x] = p;
}
last = ch[cur][x];
}
inline void dfs(int u)
{
if (len[u] % 4 == 0 && cnt[len[u] >> 1])
ans = max(ans,len[u]);
if (u != 1 && u != 0)
cnt[len[u]]++;
for (int i = 0; i < e[u].size(); i++)
dfs(e[u][i]);
if (u != 1 && u != 0)
cnt[len[u]]--;
}
int main()
{
#ifdef AMC
freopen("AMC1.txt","r",stdin);
#endif
n = getint();
scanf("%s",s + 1);
init();
for (now = 1; now <= n; now++)
add(s[now] - 'a' + 1);
for (int i = 0; i <= tot; i++)
if (i != 1)
e[fa[i]].push_back(i);
ans = 0;
dfs(1);
printf("%d",ans);
return 0;
}