P4075 [SDOI2016]模式字符串
能字符串哈希为什么要写高科技啊。
点分治之,考虑一个子树
考虑如何判断
先序遍历
进入一个点相当于在
以后缀为例,维护
先序遍历到
然后套路地记录
处理
(对前缀找后缀,对后缀找前缀)
然后把
#include <cstdio>
#include <ext/pb_ds/hash_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
struct E
{
int v, t;
} e[2000050];
__gnu_pbds::gp_hash_table<int, int> C[2];
char a[1000050], o[1000050];
bool b[1000050], F[1000050][2], W[1000050][2];
unsigned long long q, P[1000050], H[1000050], Z[1000050][2];
int T, n, m, c, l, R, s[1000050], p[1000050], d[1000050], D[1000050], h[1000050];
void A(int u, int v)
{
e[++c] = {v, h[u]};
h[u] = c;
}
void X(int u, int k, int t)
{
s[u] = 1;
p[u] = 0;
for (int i = h[u], v; i; i = e[i].t)
if (!b[v = e[i].v] && v != k)
X(v, u, t), s[u] += s[v], p[u] = max(p[u], s[v]);
if (p[R] > (p[u] = max(p[u], t - s[u])))
R = u;
}
void Y(int u, int k)
{
H[d[D[l++] = u]] = H[d[u] - 1] * 233 + a[u];
if (d[u] >= m)
W[u][0] = F[d[u]][0] = F[d[u] - m][0] & H[d[u]] - H[d[u] - m] * P[m] == Z[m][0],
W[u][1] = F[d[u]][1] = F[d[u] - m][1] & H[d[u]] - H[d[u] - m] * P[m] == Z[m][1];
else
W[u][0] = F[d[u]][0] = H[d[u]] == Z[m][0] - Z[m - d[u]][0] * P[d[u]],
W[u][1] = F[d[u]][1] = H[d[u]] == Z[m][1] - Z[m - d[u]][1] * P[d[u]];
for (int i = h[u], v; i; i = e[i].t)
if (!b[v = e[i].v] && v != k)
d[v] = d[u] + 1, Y(v, u);
}
void Q(int u, int k)
{
H[1] = a[u];
W[u][0] = F[1][0] = C[0][1] = a[u] == o[b[u] = 1];
W[u][1] = F[1][1] = C[1][1] = a[u] == o[m];
for (int i = h[u], v; i; i = e[i].t)
if (!b[v = e[i].v] && v != k)
{
d[v] = 2;
Y(v, u);
for (int j = 0; j < l; ++j)
q += W[D[j]][0] * C[1][(m + 1 - d[D[j]] % m) % m] + W[D[j]][1] * C[0][(m + 1 - d[D[j]] % m) % m];
for (int j = 0; j < l; ++j)
C[0][d[D[j]] % m] += W[D[j]][0], C[1][d[D[j]] % m] += W[D[j]][1];
l = 0;
}
C[0].clear();
C[1].clear();
for (int i = h[u], v; i; i = e[i].t)
if (!b[v = e[i].v] && v != k)
R = 0, X(v, u, s[v]), Q(R, u);
}
int main()
{
p[0] = 1e9;
F[0][0] = F[0][1] = 1;
for (int i = P[0] = 1; i <= 1e6; ++i)
P[i] = P[i - 1] * 233;
scanf("%d", &T);
while (T--)
{
scanf("%d%d%s", &n, &m, a + 1);
for (int i = 1, u, v; i < n; ++i)
scanf("%d%d", &u, &v), A(u, v), A(v, u);
scanf("%s", o + 1);
for (int i = 1; i <= m; ++i)
Z[i][0] = Z[i - 1][0] * 233 + o[m - i + 1], Z[i][1] = Z[i - 1][1] * 233 + o[i];
R = 0;
X(1, 0, n);
Q(R, 0);
printf("%llu\n", q);
c = q = 0;
for (int i = 1; i <= n; ++i)
h[i] = b[i] = 0;
}
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工具