1 条题解
-
0
自动搬运
来自洛谷,原作者为

5k_sync_closer
数据结构真可爱。搬运于
2025-08-24 22:45:05,当前版本为作者最后更新于2023-02-28 10:51:58,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
谁告诉你 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; }
- 1
信息
- ID
- 8373
- 时间
- 3000ms
- 内存
- 512MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者