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)\) 个结点的一棵树, ...
随机推荐
- 基于python的租房网站-房屋出租租赁系统(python+django+vue)
该项目是基于python/django/vue开发的房屋租赁系统/租房平台,作为本学期的课程作业作品.欢迎大家提出宝贵建议. 功能介绍 平台采用B/S结构,后端采用主流的Python+Django进行 ...
- java - 运行可执行文件 (.exe)
package filerun; import java.io.File; import java.io.IOException; public class RunExe { public stati ...
- Pickle反序列化学习
什么是Pickle? 很简单,就是一个python的序列化模块,方便对象的传输与存储.但是pickle的灵活度很高,可以通过对opcode的编写来实现代码执行的效果,由此引发一系列的安全问题 Pick ...
- [转帖]如何不耍流氓的做运维之-SHELL脚本
https://www.cnblogs.com/luoahong/articles/8504691.html 前言 大家都是文明人,尤其是做运维的,那叫一个斯文啊.怎么能耍流氓呢?赶紧看看,编写SHE ...
- SQLServer数据库JDBC连接串参数的简单学习
SQLServer数据库JDBC连接串参数的简单学习 背景 前段时间一直跟同事一起处理SQLServer 比其他数据库的deadlock更多的问题. 涉及到了几个驱动的参数. 想着问题基本上告一段落, ...
- 【转帖】Linux中如何取消ln链接?(linuxln取消)
https://www.dbs724.com/163754.html Linux系统使用ln命令可以快速创建链接,ln链接是指把文件和目录链接起来,当改变源时可以快速地改变整个目录下的文件和目录.有时 ...
- 【转帖】eBay 云计算“网”事:网络超时篇
https://www.infoq.cn/article/JmCbkA0XX9NqrcX6loIo eBay技术荟 2020-06-19 本文字数:5508 字 阅读完需:约 18 分钟 导读 eBa ...
- [转帖]ipset命令介绍与基本使用
一. 介绍 ipset命令是用于管理内核中IP sets模块的,如iptables之于netfilter.ipset字面意思是一些IP地址组成一个集合(set).但是ipset用于用于存储IP地址,整 ...
- 开源即时通讯(IM)项目OpenIM源码部署流程
由于 OpenIM 依赖的组件较多,开发者需求不一,导致 OpenIM 部署一直被人诟病,经过几次迭代优化,包括依赖的组件 compose 的一键部署,环境变量设置一次,全局生效,以及脚本重构,目前 ...
- element实现大图预览和图片动态加载
element的el-image组件支持大图预览模式,但需要和小图模式配合使用,项目中刚好有需求需要直接使用大图预览并且需要支持图片的动态加载,研究了一下el-image组件的源码发现el-image ...