P5685 [JSOI2013] 快乐的 JYY 题解
简化题意:公共回文串计数。
对两个串分别建 PAM,然后同时遍历它们,每次只走它们共有的边,
此时能遍历到的点就是两个串的所有公共回文串,考虑每个点的贡献。
对 PAM 上每个点
#include <cstdio>
#include <algorithm>
using namespace std;
long long q;
struct T
{
char u[50050];
int n, o, z, l[50050], f[50050], d[50050], c[50050][26];
int F(int x)
{
while (u[n] != u[n - l[x] - 1])
x = f[x];
return x;
}
void I(int x)
{
++n;
int p = F(z);
if (!c[p][x])
l[c[p][x] = ++o] = l[p] + 2, f[c[p][x]] = p != 1 ? c[F(f[p])][x] : 0;
++d[z = c[p][x]];
}
void D()
{
for (int i = o; i >= 2; --i)
d[f[i]] += d[i];
}
} X, Y;
void D(int x, int y, int d)
{
if (x >= 2 && y >= 2)
q += 1ll * X.d[x] * Y.d[y];
for (int i = 0; i < 26; ++i)
if (X.c[x][i] && Y.c[y][i])
D(X.c[x][i], Y.c[y][i], d + 2);
}
int main()
{
X.l[X.f[0] = X.o = 1] = -1;
Y.l[Y.f[0] = Y.o = 1] = -1;
scanf("%s%s", X.u + 1, Y.u + 1);
for (int i = 1; X.u[i]; ++i)
X.I(X.u[i] - 'A');
for (int i = 1; Y.u[i]; ++i)
Y.I(Y.u[i] - 'A');
X.D();
Y.D();
D(0, 0, 0);
D(1, 1, -1);
printf("%lld", q);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具