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)\) 个结点的一棵树, ...
随机推荐
- Verilog仿真实践
Verilog必须掌握 逻辑仿真工具(VCS)和逻辑综合工具(DC) AndOR module AndOr( output X,Y, input A,B,C ); // A B进行按位与运算 assi ...
- 【面试题精讲】Java Stream排序的实现方式
首发博客地址 系列文章地址 如何使用Java Stream进行排序 在Java中,使用Stream进行排序可以通过sorted()方法来实现.sorted()方法用于对Stream中的元素进行排序操作 ...
- [转帖][java] GC (Allocation Failure)日志分析
日前查看某个程序的日志,发现一直在报GC相关的信息,不确定这样的信息是代表正确还是不正确,所以正好借此机会再复习下GC相关的内容: 以其中一行为例来解读下日志信息: [GC (Allocation F ...
- [转帖]br备份时排除某个库
https://tidb.net/blog/2a88149e?utm_source=tidb-community&utm_medium=referral&utm_campaign=re ...
- [转帖]Linux之bash反弹shell原理浅析
环境 攻击机:kali ip:192.168.25.144 靶 机:centos ip:192.168.25.142 过程 kali 监听本地8888端口 靶机 ...
- 【转帖】Windows Server 2016与旧版本系统比较
一.性能和可扩性 特征描述 Windows Server 2012/2012 R2 标准版和数据中心 Windows Server 2016 标准版和数据中心 物理内存(主机)支持 每个物理服务器至多 ...
- isolcpus的学习与了解
isolcpus的学习与了解 前言 最近一直跟同事说要进行CPU的bind bind到具体的core 当时还一直装B, 说这样能够提高性能. 但是今天起床早上查看资料时发现,其实是先设置隔离的. 让操 ...
- 海量数据 vastbase G100 V2.2安装简单总结
海量数据vastbase G100 V2.2 安装总结 背景说明 最近进行信创四期的数据库兼容性验证, 获取了海量数据的一个信创名录内的安装介质. 一直忙于出差, 今天晚上趁着冬至回家比较早在家里进行 ...
- HanLP — 感知机(Perceptron) -- Python
HanLP - 感知机(Perceptron) 感知机 感知机是根据输入实例的特征向量 x 对其进行二类分类的线性模型: \[f(x)=sign(w\cdot x+b) \] 感知机模型对应于输入空间 ...
- 使用perfdog如何测试微信小程序
测试微信小程序和测试其他app唯一的不同点是如何在app中选中要测试的小程序 至于其他的基本操作可查看https://www.cnblogs.com/lihongtaoya/p/15140610.ht ...