P9067 [Ynoi Easy Round 2022] 虚空处刑 题解
谁告诉你 Ynoi 就要手写数据结构了?
维护 map<int, list<int>> C[N]
,
lxl 说过,这种邻域信息维护父亲一定死,所以令
这里没必要从
unordered_map
跑不过 map
。
#include <map>
#include <list>
#include <cstdio>
using namespace std;
struct E
{
int v, t;
} e[1000050];
map<int, list<int>> C[1000050];
int n, m, c, a[1000050], s[1000050], f[1000050], g[1000050], h[1000050];
void A(int u, int v)
{
e[++c] = {v, h[u]};
h[u] = c;
}
int F(int x) { return x == f[x] ? x : f[x] = F(f[x]); }
void L(int u, int v)
{
f[v = F(v)] = u = F(u);
s[u] += s[v];
}
void D(int u, int k)
{
for (int i = h[u], v; i; i = e[i].t)
if ((v = e[i].v) != k)
{
g[v] = u;
if (a[v] == a[u])
L(u, v);
else
C[F(u)][a[v]].push_back(v);
D(v, u);
}
}
void M(int x, int y)
{
if (C[x].size() < C[y].size())
swap(C[x], C[y]);
for (auto i : C[y])
C[x][i.first].splice(C[x][i.first].end(), i.second);
C[y].clear();
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = 2, x; i <= n; ++i)
scanf("%d", &x), A(x, i);
for (int i = 1; i <= n; ++i)
scanf("%d", a + i), s[f[i] = i] = 1;
D(1, 0);
for (int i = 0, o, x, y, z; i < m; ++i)
{
scanf("%d%d", &o, &x);
x = F(x);
if (o & 1)
{
scanf("%d", &y);
if (a[x] == y)
continue;
auto l = C[x][y];
for (auto i : l)
if (y == a[i] && x != F(i))
L(x, i), M(x, i);
if (y == a[z = F(g[x])])
L(z, x), M(z, x);
else if (z)
C[z][y].push_back(x);
C[F(x)][a[x] = y].clear();
}
else
printf("%d\n", s[x]);
}
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工具