NC200179 Colorful Tree
题目
题目描述
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
输入
5
1 2
2 3
3 4
2 5
1 2 1 2 3
11
Q 1
Q 2
Q 3
Q 4
U 5 1
Q 1
U 3 2
Q 1
Q 2
U 5 4
Q 1
输出
2
2
0
-1
3
2
2
0
题解
知识点:DFS序,LCA,STL。
对于一种颜色,我们新加入一个点 \(x\) ,考虑其贡献。设dfn序左右最近的两个点 \(u,v\) ,那么其贡献为:
\]
可以分类讨论验证,首先一定是选择dfn序最近的两点,其次无论 \(x\) 位于 \(u,v\) 中间,还是一侧,这个式子都是满足的。其中对于一侧情况,我们统一取第一个点和最后一个点,可以同时满足左侧和右侧以及只有一个点的情况。
因此,我们对每个颜色的点建一个 set
,排序规则采用dfn序从小到大,更新查找时使用二分即可,增加删除可以写在同一个函数里。对于求距离,使用倍增LCA即可。
初始时,将每个点都加一遍。
时间复杂度 \(O((n+m)\log n)\)
空间复杂度 \(O(n \log n)\)
代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
struct Graph {
struct edge {
int v, nxt;
};
int idx;
vector<int> h;
vector<edge> e;
Graph(int n = 0, int m = 0) { init(n, m); }
void init(int n, int m) {
idx = 0;
h.assign(n + 1, 0);
e.assign(m + 1, {});
}
void add(int u, int v) {
e[++idx] = { v,h[u] };
h[u] = idx;
}
};
const int N = 100007;
Graph g;
namespace LCA {
const int lgN = 16;
int dep[N], f[lgN + 7][N];
void dfs(int u, int fa = 0) {
f[0][u] = fa;
dep[u] = dep[fa] + 1;
for (int i = 1;i <= lgN;i++) f[i][u] = f[i - 1][f[i - 1][u]];
for (int i = g.h[u];i;i = g.e[i].nxt) {
int v = g.e[i].v;
if (v == fa) continue;
dfs(v, u);
}
}
int LCA(int u, int v) {
if (dep[u] < dep[v]) swap(u, v);
for (int i = lgN;i >= 0;i--) {
if (dep[f[i][u]] >= dep[v]) u = f[i][u];
if (u == v) return u;
}
for (int i = lgN;i >= 0;i--) {
if (f[i][u] != f[i][v]) {
u = f[i][u];
v = f[i][v];
}
}
return f[0][u];
}
int dis(int u, int v) { return dep[u] + dep[v] - 2 * dep[LCA(u, v)]; }
}
int dfncnt;
int rdfn[N];
void dfs(int u, int fa) {
rdfn[u] = ++dfncnt;
for (int i = g.h[u];i;i = g.e[i].nxt) {
int v = g.e[i].v;
if (v == fa) continue;
dfs(v, u);
}
}
struct cmp {
bool operator()(int a, int b) const {
return rdfn[a] < rdfn[b];
}
};
int c[N];
set<int, cmp> st[N];
int ans[N];
void update(int x, int f) {
if (f == -1) st[c[x]].erase(x);
if (st[c[x]].size()) {
auto it = st[c[x]].lower_bound(x);
auto it1 = st[c[x]].begin();
auto it2 = prev(st[c[x]].end());
if (it != st[c[x]].begin() && it != st[c[x]].end()) {
it1 = it;
it2 = prev(it);
}
ans[c[x]] += f * (
LCA::dis(*it1, x)
+ LCA::dis(*it2, x)
- LCA::dis(*it1, *it2)
) / 2;
}
if (f == 1) st[c[x]].insert(x);
}
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n;
cin >> n;
g.init(n, n << 1);
for (int i = 1;i <= n - 1;i++) {
int u, v;
cin >> u >> v;
g.add(u, v);
g.add(v, u);
}
dfs(1, 0);
LCA::dfs(1);
for (int i = 1;i <= n;i++)
cin >> c[i], update(i, 1);
int m;
cin >> m;
while (m--) {
char op;
cin >> op;
if (op == 'Q') {
int col;
cin >> col;
cout << (st[col].size() ? ans[col] : -1) << '\n';
}
else {
int x, col;
cin >> x >> col;
update(x, -1);
c[x] = col;
update(x, 1);
}
}
return 0;
}
NC200179 Colorful Tree的更多相关文章
- 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 ...
- hdu6035 Colorful Tree 树形dp 给定一棵树,每个节点有一个颜色值。定义每条路径的值为经过的节点的不同颜色数。求所有路径的值和。
/** 题目:hdu6035 Colorful Tree 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6035 题意:给定一棵树,每个节点有一个颜色值.定 ...
- AtCoder Beginner Contest 133 F Colorful Tree
Colorful Tree 思路: 如果强制在线的化可以用树链剖分. 但这道题不强制在线,那么就可以将询问进行差分,最后dfs时再计算每个答案的修改值, 只要维护两个数组就可以了,分别表示根节点到当前 ...
- HDU 6035 - Colorful Tree | 2017 Multi-University Training Contest 1
/* HDU 6035 - Colorful Tree [ DFS,分块 ] 题意: n个节点的树,每个节点有一种颜色(1~n),一条路径的权值是这条路上不同的颜色的数量,问所有路径(n*(n-1)/ ...
- [HDU6793] Tokitsukaze and Colorful Tree
题目 又是一个条历新年,窗前的灼之花又盛开了. 时隔多年,现在只有这一棵树上盛开着残存的 \(n\) 朵灼之花了. 尽管如此,这些灼之 花仍散发出不同色彩的微弱的光芒. 灼之花的生命极为短暂,但它的花 ...
- Colorful tree
cnbb 我被数组清零卡了一天.. 子树改色询问子树颜色数.. 先考虑颜色为x的节点对祖先答案的贡献,那么我们考虑把所有这些节点都搞出来,按dfs序排序,然后考虑每个节点a掌管的祖先是它和按dfs序的 ...
- 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 ...
- HDU-6035:Colorful Tree(虚树+DP)
这里有三道长得像的题: 一:HDU6036: There is a tree with nn nodes, each of which has a type of color represented ...
- ABC133F - Colorful Tree
ABC133FColorful Tree 题意 给定一颗边有颜色和权值的树,多次询问,每次询问,首先更改颜色为x的边的权值为y,然后输出u到v的距离. 数据都是1e5量级的. 思路 我自己一开始用树链 ...
- HDU6035 Colorful Tree
题目链接:https://vjudge.net/problem/HDU-6035 题目大意: 多样例输入. 对于每一个样例,给出 n \((2 \le n \le 200000)\) 个结点的一棵树, ...
随机推荐
- MySQL 查询索引失效及如何进行索引优化
本文为博主原创,未经允许不得转载: 我们都知道创建索引的目的是快速从整体集合中选择性地读取满足条件的一部分集合.mysql中一张表是可以支持多个索引的.但是,你写sql语句的时候,并没有主动指定使用哪 ...
- Manjaro Linux永久修改主机名
技术背景 Linux系统中默认的主机名可以通过hostname指令进行查询,一般默认的是一串的随机字符串: [dechin@dechin-20n2s01200 numba]$ hostname dec ...
- idea 修改 jsp文件之后不生效问题
- Qt5.9 UI设计(三)——添加UI、类及资源文件
前言 设计一个软件,最简单的方式就是把控件直接往UI上放,然后再把功能实现了.这样可以实现基本的功能,但是界面不能缩放,如果拖动软件改变界面的大小,界面上的控件就会乱成一团,或者是界面的控件压根就不会 ...
- [转帖]OceanBase 4.2.1 LTS 发版 | 一体化数据库首个长期支持版本
2013.11.20 https://open.oceanbase.com/blog/7746655008?_gl=1*1qv10rf*_ga*Nzk3MjIxOTk0LjE3MDI2MTAxMzk. ...
- Kubeadm 安装支持IPV6 K8S1.28.x的简单过程
Kubeadm 安装支持IPV6 K8S的简单过程 背景 手贱 找了一个晚上想尝试安装一个K8S集群 并且可以支持IPV6 协议栈的 然后就开始各种百度. 各种处理 找到了一堆歪门邪道. 但是还不知道 ...
- [转帖]MySQL Connect/J 8.0时区陷阱
https://juejin.cn/post/6844904023015817224 最近公司正在升级Spring Boot版本(从1.5升级到2.1),其间踩到一个非常隐晦的MySQL时区陷阱, ...
- parquet极简学习
parquet极简学习 摘要 parquet的概念: Parquet文件是一种列式存储文件格式,广泛应用于大数据处理框架, 如Apache Hadoop和Apache Spark. 它通过将数据组织成 ...
- [转帖]PG-用户|角色管理
https://www.cnblogs.com/binliubiao/p/14415203.html 1. 角色 决定发起连接的命令的初始访问权限.在PG中,角色和用户相当于是一样的对象.区别在于 ...
- [转帖]在麒麟Linux安装Postgis
https://jimolonely.github.io/tech/linux/install-postgis-kylin/ 接着上一篇在麒麟linux上安装Postgresql12.5 ,我们来安装 ...