洛谷U41492(树上启发式合并)
考虑非\(O(n^2)\)的预处理。一遍dfs时,check某颜色有没有的数组何时清空很尴尬:得到某树答案后如果不清,则影响接下来兄弟树的搜索;如果清了,父亲节点又难以收集答案。
解决方法:先让儿子们各顾各的家,算一遍各自的答案(假如能算),check清就清了吧。然后考虑人为优化,即重链求完后等一等!先别清!然后将轻链重新扫一遍,也不清check数组的。代码中的keep就控制是否要清。这样轻链扫两遍,重链扫一遍,就得到了儿子们和父亲的答案,随机数据下复杂度\(O(nlogn)\)。
const int maxn = 1e5 + 5;
int n, m, u, v, c[maxn];
int size[maxn], son[maxn], ans[maxn];
bool check[maxn];
vector<int> adj[maxn];
void dfs1(int cur, int fa) {
size[cur] = 1;
for (int i : adj[cur])
if (i != fa) {
dfs1(i, cur);
size[cur] += size[i];
if (size[i] > size[son[cur]])
son[cur] = i;
}
}
int dfs2(int cur, int fa, int keep) {
if (keep) {
for (int i : adj[cur])
if (i != fa && i != son[cur])
dfs2(i, cur, keep);
}
int res = 0;
if (son[cur]) res += dfs2(son[cur], cur, keep);
for (int i : adj[cur])
if (i != fa && i != son[cur])
res += dfs2(i, cur, 0);
if (!check[c[cur]]) res++, check[c[cur]] = 1;
if (keep) {
ans[cur] = res;
if (cur != son[fa]) mset(check, 0);
}
return res;
}
int main() {
read(n);
rep(i, 1, n - 1) {
read(u), read(v);
adj[u].push_back(v);
adj[v].push_back(u);
}
rep(i, 1, n) read(c[i]);
dfs1(1, 0);
dfs2(1, 0, 1);
for (read(m); m--; ) {
read(u);
writeln(ans[u]);
}
return 0;
}
洛谷U41492(树上启发式合并)的更多相关文章
- 【Luogu U41492】树上数颜色——树上启发式合并(dsu on tree)
(这题在洛谷主站居然搜不到--还是在百度上偶然看到的) 题目描述 给一棵根为1的树,每次询问子树颜色种类数 输入输出格式 输入格式: 第一行一个整数n,表示树的结点数 接下来n-1行,每行一条边 接下 ...
- dsu on tree (树上启发式合并) 详解
一直都没出过算法详解,昨天心血来潮想写一篇,于是 dsu on tree 它来了 1.前置技能 1.链式前向星(vector 建图) 2.dfs 建树 3.剖分轻重链,轻重儿子 重儿子 一个结点的所有 ...
- [洛谷U40581]树上统计treecnt
[洛谷U40581]树上统计treecnt 题目大意: 给定一棵\(n(n\le10^5)\)个点的树. 定义\(Tree[l,r]\)表示为了使得\(l\sim r\)号点两两连通,最少需要选择的边 ...
- 树上启发式合并(dsu on tree)
树上启发式合并属于暴力的优化,复杂度O(nlogn) 主要解决的问题特点在于: 1.对于树上的某些信息进行查询 2.一般问题的解决不包含对树的修改,所有答案可以离线解决 算法思路:这类问题的特点在于父 ...
- dsu on tree 树上启发式合并 学习笔记
近几天跟着dreagonm大佬学习了\(dsu\ on\ tree\),来总结一下: \(dsu\ on\ tree\),也就是树上启发式合并,是用来处理一类离线的树上询问问题(比如子树内的颜色种数) ...
- 树上启发式合并(dsu on tree)学习笔记
有丶难,学到自闭 参考的文章: zcysky:[学习笔记]dsu on tree Arpa:[Tutorial] Sack (dsu on tree) 先康一康模板题吧:CF 600E($Lomsat ...
- 神奇的树上启发式合并 (dsu on tree)
参考资料 https://www.cnblogs.com/zhoushuyu/p/9069164.html https://www.cnblogs.com/candy99/p/dsuontree.ht ...
- hdu6191(树上启发式合并)
hdu6191 题意 给你一棵带点权的树,每次查询 \(u\) 和 \(x\) ,求以 \(u\) 为根结点的子树上的结点与 \(x\) 异或后最大的结果. 分析 看到子树,直接上树上启发式合并,看到 ...
- Codeforces 208E - Blood Cousins(树上启发式合并)
208E - Blood Cousins 题意 给出一棵家谱树,定义从 u 点向上走 k 步到达的节点为 u 的 k-ancestor.多次查询,给出 u k,问有多少个与 u 具有相同 k-ance ...
- Codeforces 600E - Lomsat gelral(树上启发式合并)
600E - Lomsat gelral 题意 给出一颗以 1 为根的树,每个点有颜色,如果某个子树上某个颜色出现的次数最多,则认为它在这课子树有支配地位,一颗子树上,可能有多个有支配的地位的颜色,对 ...
随机推荐
- java获取多个汉字的拼音首字母
本文属于http://java.chinaitlab.com/base/803353.html原创!!! public class PinYin2Abbreviation { // 简体中文的编码范围 ...
- Python之list的创建以及使用
list是一种有序的集合,可以随意添加和删除里面的元素. 空的list的定义:L = [] list当中的元素用[]概括起来. 在list当中可以使用索引来进行访问: 在这里我们要注意我们在进行索引的 ...
- java多线程编程——同步器Exchanger
类java.util.concurrent.Exchanger提供了一个同步点,在这个同步点,一对线程可以交换数据.每个线程通过exchange()方法的入口提供数据给他的伙伴线程,并接收他的伙伴线程 ...
- LinkedHashMap和HashMap的区别
一.问题描述: 前几天写webservices接口,需要同步人力资源,涉及到添加顺序:主账号需要添加在次账号之前,直接上级需要添加在下级之前.解析xml之后直接封装在HashMap中,导致取对象时顺序 ...
- 使用myeclipse开发Servlet
1.在myeclipse中创建一个web工程 2.在src目录下建立一个包并建立一个Servlet(myeclipse会自把Servlet映射到web.xml文件中) 3.发布工程,实际上就是把web ...
- Alert---点击拍照弹出对话框
/** * 照片对话框 *AlertDialog */ private void PhotoDialog() { AlertDialog.Builder builder = new Builder(m ...
- nyoj42欧拉回路
一笔画问题 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描述 zyc从小就比较喜欢玩一些小游戏,其中就包括画一笔画,他想请你帮他写一个程序,判断一个图是否能够用一笔画下 ...
- 解决iText+freemark导出pdf不支持base64的解决办法
工具类: package test; import java.io.IOException ; import org.w3c.dom.Element ; import org.xhtmlrendere ...
- PythonNote02_HTML标签
<!DOCTYPE> <html> <head> <meta charset = "utf-8" /> <meta name= ...
- linux安装thrift
安装配置Thrift Thrift的编译器使用C++编写的,在安装编译器之前,首先应该保证操作系统基本环境支持C++的编译,安装相关依赖的软件包,如下所示 sudo yum install autom ...