HDU6504 Problem E. Split The Tree【dsu on tree】
Problem E. Split The Tree
Problem Description
You are given a tree with n vertices, numbered from 1 to n. ith vertex has a value wi
We define the weight of a tree as the number of different vertex value in the tree.
If we delete one edge in the tree, the tree will split into two trees. The score is the sum of these two trees’ weights.
We want the know the maximal score we can get if we delete the edge optimally
给出一棵根为\(1\)的树,每个节点有权值,现在断开一条边,把树一分为二,记一棵树的贡献为这棵树里所有节点中不同权值的数量,现在要计算断开边之后两棵树的贡献的和的最大值
现在有一棵子树,为了得到答案,我们只要知道它里面出现过的各个权值有多少个,记原树中各个权值出现的数量是\(cnt[i]\),分开之后的一棵子树的各个权值出现的数量使\(dcnt[i]\),只要出现\(dcnt[i]\ne cnt[i]\ and\ dcnt[i]\ne 0\),对答案的贡献就\(+1\),这个可以\(O(1)\)处理,那么就可以树上启发式合并了
//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1e5+7;
int n,w[MAXN],ret,tmp,cnt[MAXN],dcnt[MAXN],son[MAXN],sz[MAXN],st[MAXN],ed[MAXN],id[MAXN],dfn;
vector<int> G[MAXN];
void dfs(int u){
sz[u] = 1; son[u] = 0;
st[u] = ++dfn; id[dfn] = u;
for(int v : G[u]){
dfs(v);
sz[u] += sz[v];
if(sz[v]>sz[son[u]]) son[u] = v;
}
ed[u] = dfn;
}
void update(int val, int inc){
if(inc==1){
if(!dcnt[val]) tmp++;
dcnt[val]++;
if(dcnt[val]==cnt[val]) tmp--;
}
else{
if(dcnt[val]==cnt[val]) tmp++;
dcnt[val]--;
if(!dcnt[val]) tmp--;
}
}
void search(int u, bool clear){
for(int v : G[u]) if(v!=son[u]) search(v,true);
if(son[u]) search(son[u],false);
for(int v : G[u]) if(v!=son[u]) for(int i = st[v]; i <= ed[v]; i++) update(w[id[i]],1);
update(w[u],1);
ret = max(ret,tmp);
if(clear) for(int i = st[u]; i <= ed[u]; i++) update(w[id[i]],-1);
}
void solve(){
dfn = 0;
for(int i = 1; i <= n; i++) G[i].clear();
for(int i = 2; i <= n; i++){
int par; scanf("%d",&par);
G[par].push_back(i);
}
tmp = 0;
for(int i = 1; i <= n; i++){
scanf("%d",&w[i]);
if(!cnt[w[i]]) tmp++;
cnt[w[i]]++;
}
ret = tmp;
dfs(1);
search(1,true);
printf("%d\n",ret);
for(int i = 1; i <= n; i++) cnt[w[i]]--;
}
int main(){
while(scanf("%d",&n)!=EOF) solve();
return 0;
}
HDU6504 Problem E. Split The Tree【dsu on tree】的更多相关文章
- 【DSU on tree】【CF741D】Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths
Description 给定一棵 \(n\) 个节点的树,每条边上有一个字符,字符集大小 \(22\),求每个节点的子树内最长的简单路径使得路径上的字符经过重排后构成回文串. Limitation \ ...
- CF 570D. Tree Requests [dsu on tree]
传送门 题意: 一棵树,询问某棵子树指定深度的点能否构成回文 当然不用dsu on tree也可以做 dsu on tree的话,维护当前每一个深度每种字母出现次数和字母数,我直接用了二进制.... ...
- HDU1325 Is It A Tree? 【并查集】
Is It A Tree? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
- 2017 Multi-University Training Contest - Team 9 1001&&HDU 6161 Big binary tree【树形dp+hash】
Big binary tree Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)T ...
- cdoj32-树上战争(Battle on the tree) 【记忆化搜索】
http://acm.uestc.edu.cn/#/problem/show/32 树上战争(Battle on the tree) Time Limit: 12000/4000MS (Java/Ot ...
- BZOJ2588 Count on a tree 【树上主席树】
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MB Submit: 7577 Solved: 185 ...
- POJ 3237 Tree 【树链剖分】+【线段树】
<题目链接> 题目大意: 给定一棵树,该树带有边权,现在对该树进行三种操作: 一:改变指定编号边的边权: 二:对树上指定路径的边权全部取反: 三:查询树上指定路径的最大边权值. 解题分析: ...
- LC 431. Encode N-ary Tree to Binary Tree 【lock,hard】
Design an algorithm to encode an N-ary tree into a binary tree and decode the binary tree to get the ...
- HDU6430 Problem E. TeaTree【dsu on tree】
Problem E. TeaTree Problem Description Recently, TeaTree acquire new knoledge gcd (Greatest Common D ...
随机推荐
- CSS 奇技淫巧:动态高度过渡动画
这个问题源自于掘金上的一个留言,一个朋友问到,为什么我下面这段代码的高度过渡动画失效了? 伪代码大概是这样: { height: unset; transition: all 0.3s linear; ...
- 【对线面试官】Java 反射&&动态代理
// 抽象类,定义泛型<T> public abstract class BaseDao<T> { public BaseDao(){ Class clazz = this.g ...
- 【Linux】如何查找命令及历史记录history
如何查找命令及历史记录 文章目录 如何查找命令及历史记录 1.如何找到一个命令 2.命令的历史记录 3.一些实用的快捷键 4.小结 5.参考资料 如何找到一个命令.命令的历史记录.一些实用的快捷键.总 ...
- ps 2020 下载
一款极具实用价值的作图软件--ps,由于正版价格昂贵,所以这里分享破解版的资源.b话少说,下面是下载链接和安装步骤: 下载链接: 百度网盘链接:https://pan.baidu.com/s/1XPf ...
- CTFhub刷题记录
一 [WesternCTF2018]shrine 没什么好说的,SSTI模版注入类问题,过滤了()但是我们不慌.开始注入,{{29*3}}测试通过. 发现是jinjia2的模版注入.关键点在于没有() ...
- cursor pin s和cursor pin s wait on x
1.cursor pin s是一个共享锁,一般情况下是因为发生在SQL短时间内大量执行 案例:在生产库中,突然出现大量的cursor pin s的等待,询问是否有动作后,同事说有编译存储过程(被误导了 ...
- SpringBoot 好“吃”的启动原理
原创:西狩 编写日期 / 修订日期:2020-12-30 / 2020-12-30 版权声明:本文为博主原创文章,遵循 CC BY-SA-4.0 版权协议,转载请附上原文出处链接和本声明. 不正经的前 ...
- Mac中安装Git
Mac 安装git 打开Mac终端输入git命令 如果出现以下代码说明已经安装 usage: git [--version] [--help] [-C <path>] [-c <na ...
- Java中的深浅拷贝问题,你清楚吗?
一.前言 拷贝这个词想必大家都很熟悉,在工作中经常需要拷贝一份文件作为副本.拷贝的好处也很明显,相较于新建来说,可以节省很大的工作量.在Java中,同样存在拷贝这个概念,拷贝的意义也是可以节省创建对象 ...
- 浅析鸿蒙中的 Gn 与 Ninja(一)
目录: Ninja简介 make 的 3 个特性 举例说明Ninja 的用法 如何向构建工具 Ninja 描述构建图 后记 鸿蒙系统的编译构建是基于 Gn 和 Ninja 完成的,那么 Gn 和 Ni ...