题目链接

题目

题目描述

A tree structure with some colors associated with its vertices and a sequence of commands on it are given. A command is either an update operation or a query on the tree. Each of the update operations changes the color of a specified vertex, without changing the tree structure. Each of the queries asks the number of edges in the minimum connected subgraph of the tree that contains all the vertices of the specified color.

Your task is to find answers of each of the queries, assuming that the commands are performed in the given order.

输入描述

The input consists of a single test case of the following format.

n

\(a_1\) \(b_1\)

. . .

\(a_{n−1}\) \(b_{n−1}\)

\(c_1 ... c_n\)

m

\(command_1\)

. . .

\(command_m\)

The first line contains an integer n \((2 \leq n \leq 100000)\) , the number of vertices of the tree. The vertices are numbered 1 through n. Each of the following n−1 lines contains two integers \(a_i (1 \leq a_i \leq n)\) and \(b_i (1 \leq b_i \leq n)\) , meaning that the i-th edge connects vertices \(a_i\) and \(b_i\) . It is ensured that all the vertices are connected, that is, the given graph is a tree. The next line contains n integers, \(c_1\) through \(c_n\) , where \(c_j (1 \leq c_j \leq 100000)\) is the initial color of vertex j. The next line contains an integer m \((1 \leq m \leq 100000)\) , which indicates the number of commands. Each of the following m lines contains a command in the following format.

U \(x_k\) \(y_k\)

or

Q \(y_k\)

When the k-th command starts with U, it means an update operation changing the color of vertex \(x_k (1 \leq x_k \leq n)\) to \(y_k (1 \leq y_k \leq 100000)\) . When the k-th command starts with Q, it

means a query asking the number of edges in the minimum connected subgraph of the tree that contains all the vertices of color \(y_k (1 \leq y_k \leq 100000)\) .

输出描述

For each query, output the number of edges in the minimum connected subgraph of the tree containing all the vertices of the specified color. If the tree doesn’t contain any vertex of the specified color, output -1 instead.

示例1

输入

  1. 5
  2. 1 2
  3. 2 3
  4. 3 4
  5. 2 5
  6. 1 2 1 2 3
  7. 11
  8. Q 1
  9. Q 2
  10. Q 3
  11. Q 4
  12. U 5 1
  13. Q 1
  14. U 3 2
  15. Q 1
  16. Q 2
  17. U 5 4
  18. Q 1

输出

  1. 2
  2. 2
  3. 0
  4. -1
  5. 3
  6. 2
  7. 2
  8. 0

题解

知识点:DFS序,LCA,STL。

对于一种颜色,我们新加入一个点 \(x\) ,考虑其贡献。设dfn序左右最近的两个点 \(u,v\) ,那么其贡献为:

\[\frac{1}{2}(dist(u,x) + dist(v,x) - dist(u,v))
\]

可以分类讨论验证,首先一定是选择dfn序最近的两点,其次无论 \(x\) 位于 \(u,v\) 中间,还是一侧,这个式子都是满足的。其中对于一侧情况,我们统一取第一个点和最后一个点,可以同时满足左侧和右侧以及只有一个点的情况。

因此,我们对每个颜色的点建一个 set ,排序规则采用dfn序从小到大,更新查找时使用二分即可,增加删除可以写在同一个函数里。对于求距离,使用倍增LCA即可。

初始时,将每个点都加一遍。

时间复杂度 \(O((n+m)\log n)\)

空间复杂度 \(O(n \log n)\)

代码

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. using ll = long long;
  4. struct Graph {
  5. struct edge {
  6. int v, nxt;
  7. };
  8. int idx;
  9. vector<int> h;
  10. vector<edge> e;
  11. Graph(int n = 0, int m = 0) { init(n, m); }
  12. void init(int n, int m) {
  13. idx = 0;
  14. h.assign(n + 1, 0);
  15. e.assign(m + 1, {});
  16. }
  17. void add(int u, int v) {
  18. e[++idx] = { v,h[u] };
  19. h[u] = idx;
  20. }
  21. };
  22. const int N = 100007;
  23. Graph g;
  24. namespace LCA {
  25. const int lgN = 16;
  26. int dep[N], f[lgN + 7][N];
  27. void dfs(int u, int fa = 0) {
  28. f[0][u] = fa;
  29. dep[u] = dep[fa] + 1;
  30. for (int i = 1;i <= lgN;i++) f[i][u] = f[i - 1][f[i - 1][u]];
  31. for (int i = g.h[u];i;i = g.e[i].nxt) {
  32. int v = g.e[i].v;
  33. if (v == fa) continue;
  34. dfs(v, u);
  35. }
  36. }
  37. int LCA(int u, int v) {
  38. if (dep[u] < dep[v]) swap(u, v);
  39. for (int i = lgN;i >= 0;i--) {
  40. if (dep[f[i][u]] >= dep[v]) u = f[i][u];
  41. if (u == v) return u;
  42. }
  43. for (int i = lgN;i >= 0;i--) {
  44. if (f[i][u] != f[i][v]) {
  45. u = f[i][u];
  46. v = f[i][v];
  47. }
  48. }
  49. return f[0][u];
  50. }
  51. int dis(int u, int v) { return dep[u] + dep[v] - 2 * dep[LCA(u, v)]; }
  52. }
  53. int dfncnt;
  54. int rdfn[N];
  55. void dfs(int u, int fa) {
  56. rdfn[u] = ++dfncnt;
  57. for (int i = g.h[u];i;i = g.e[i].nxt) {
  58. int v = g.e[i].v;
  59. if (v == fa) continue;
  60. dfs(v, u);
  61. }
  62. }
  63. struct cmp {
  64. bool operator()(int a, int b) const {
  65. return rdfn[a] < rdfn[b];
  66. }
  67. };
  68. int c[N];
  69. set<int, cmp> st[N];
  70. int ans[N];
  71. void update(int x, int f) {
  72. if (f == -1) st[c[x]].erase(x);
  73. if (st[c[x]].size()) {
  74. auto it = st[c[x]].lower_bound(x);
  75. auto it1 = st[c[x]].begin();
  76. auto it2 = prev(st[c[x]].end());
  77. if (it != st[c[x]].begin() && it != st[c[x]].end()) {
  78. it1 = it;
  79. it2 = prev(it);
  80. }
  81. ans[c[x]] += f * (
  82. LCA::dis(*it1, x)
  83. + LCA::dis(*it2, x)
  84. - LCA::dis(*it1, *it2)
  85. ) / 2;
  86. }
  87. if (f == 1) st[c[x]].insert(x);
  88. }
  89. int main() {
  90. std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  91. int n;
  92. cin >> n;
  93. g.init(n, n << 1);
  94. for (int i = 1;i <= n - 1;i++) {
  95. int u, v;
  96. cin >> u >> v;
  97. g.add(u, v);
  98. g.add(v, u);
  99. }
  100. dfs(1, 0);
  101. LCA::dfs(1);
  102. for (int i = 1;i <= n;i++)
  103. cin >> c[i], update(i, 1);
  104. int m;
  105. cin >> m;
  106. while (m--) {
  107. char op;
  108. cin >> op;
  109. if (op == 'Q') {
  110. int col;
  111. cin >> col;
  112. cout << (st[col].size() ? ans[col] : -1) << '\n';
  113. }
  114. else {
  115. int x, col;
  116. cin >> x >> col;
  117. update(x, -1);
  118. c[x] = col;
  119. update(x, 1);
  120. }
  121. }
  122. return 0;
  123. }

NC200179 Colorful Tree的更多相关文章

  1. 2017 Multi-University Training Contest - Team 1 1003&&HDU 6035 Colorful Tree【树形dp】

    Colorful Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  2. hdu6035 Colorful Tree 树形dp 给定一棵树,每个节点有一个颜色值。定义每条路径的值为经过的节点的不同颜色数。求所有路径的值和。

    /** 题目:hdu6035 Colorful Tree 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6035 题意:给定一棵树,每个节点有一个颜色值.定 ...

  3. AtCoder Beginner Contest 133 F Colorful Tree

    Colorful Tree 思路: 如果强制在线的化可以用树链剖分. 但这道题不强制在线,那么就可以将询问进行差分,最后dfs时再计算每个答案的修改值, 只要维护两个数组就可以了,分别表示根节点到当前 ...

  4. HDU 6035 - Colorful Tree | 2017 Multi-University Training Contest 1

    /* HDU 6035 - Colorful Tree [ DFS,分块 ] 题意: n个节点的树,每个节点有一种颜色(1~n),一条路径的权值是这条路上不同的颜色的数量,问所有路径(n*(n-1)/ ...

  5. [HDU6793] Tokitsukaze and Colorful Tree

    题目 又是一个条历新年,窗前的灼之花又盛开了. 时隔多年,现在只有这一棵树上盛开着残存的 \(n\) 朵灼之花了. 尽管如此,这些灼之 花仍散发出不同色彩的微弱的光芒. 灼之花的生命极为短暂,但它的花 ...

  6. Colorful tree

    cnbb 我被数组清零卡了一天.. 子树改色询问子树颜色数.. 先考虑颜色为x的节点对祖先答案的贡献,那么我们考虑把所有这些节点都搞出来,按dfs序排序,然后考虑每个节点a掌管的祖先是它和按dfs序的 ...

  7. 2017ACM暑期多校联合训练 - Team 1 1003 HDU 6035 Colorful Tree (dfs)

    题目链接 Problem Description There is a tree with n nodes, each of which has a type of color represented ...

  8. HDU-6035:Colorful Tree(虚树+DP)

    这里有三道长得像的题: 一:HDU6036: There is a tree with nn nodes, each of which has a type of color represented ...

  9. ABC133F - Colorful Tree

    ABC133FColorful Tree 题意 给定一颗边有颜色和权值的树,多次询问,每次询问,首先更改颜色为x的边的权值为y,然后输出u到v的距离. 数据都是1e5量级的. 思路 我自己一开始用树链 ...

  10. HDU6035 Colorful Tree

    题目链接:https://vjudge.net/problem/HDU-6035 题目大意: 多样例输入. 对于每一个样例,给出 n \((2 \le n \le 200000)\) 个结点的一棵树, ...

随机推荐

  1. Go 疑难杂症汇总

    1. revision v0.0.0: unknown revision v0.0.0 go get -u github.com/uudashr/gopkgs/cmd/gopkgs 报错: [root ...

  2. 6. 配置项:relabel_config

    6.1relabel_config的位置 6.2 relabel_config参数详解 1.replace 2. keep 3.drop 6.labelkeep 7.hashmod 6.3 正则表达式 ...

  3. bootstrap : 解决使图片全屏显示有空白边距的问题

    <!DOCTYPE html> <html lang="en"> <head>     <meta charset="utf-8 ...

  4. [转帖]解Bug之路-记一次JVM堆外内存泄露Bug的查找

    https://zhuanlan.zhihu.com/p/245401095 解Bug之路-记一次JVM堆外内存泄露Bug的查找 前言 JVM的堆外内存泄露的定位一直是个比较棘手的问题.此次的Bug查 ...

  5. [转帖]Oracle 创建和查看DBLink 的方法

    https://www.cnblogs.com/zhouzangood/articles/4612441.html 1.如果需要创建全局 DBLink,则需要先确定用户有创建 dblink 的权限: ...

  6. [转帖]RAC环境下误操作将数据文件添加到本地存储

    https://www.cnblogs.com/jyzhao/p/7986729.html 今天碰到个有意思的事情,有客户在Oracle RAC环境,误操作将新增的数据文件直接创建到了其中一个节点的本 ...

  7. [转帖]比较不同CPU下的分支预测

    https://plantegg.github.io/2023/04/16/%E6%AF%94%E8%BE%83%E4%B8%8D%E5%90%8CCPU%E4%B8%8B%E7%9A%84%E5%8 ...

  8. [转帖]Ipmitool跟OS下的ipmi模块之间的关系

    https://www.jianshu.com/p/71614d3288e8 OS下默认加载了ipmi的相关模块 注:此时OS下可以正常使用ipmitool命令访问本机的ipmi 设备. [root@ ...

  9. [转帖]从v8到v9,Arm服务器发展之路

    https://zhuanlan.zhihu.com/p/615344155   01 ARM:3A大作 将 CPU 的设计与制造相分离的代工模式,给 AMD 提供了高度的灵活性.第二.三代 EPYC ...

  10. 每日一库:cobra 简介

    当你需要为你的 Go 项目创建一个强大的命令行工具时,你可能会遇到许多挑战,比如如何定义命令.标志和参数,如何生成详细的帮助文档,如何支持子命令等等.为了解决这些问题,github.com/spf13 ...