Bobo has a tree with n vertices numbered by 1,2,…,n and (n-1) edges. The i-th vertex has color c i, and the i-th edge connects vertices a i and b i.
Let C(x,y) denotes the set of colors in subtree rooted at vertex x deleting edge (x,y).
Bobo would like to know R_i which is the size of intersection of C(a i,b i) and C(bi,a i) for all 1≤i≤(n-1). (i.e. |C(a i,b i)∩C(b i,a i)|)

Input

The input contains at most 15 sets. For each set:
The first line contains an integer n (2≤n≤10 5).
The second line contains n integers c 1,c 2,…,c n (1≤c_i≤n).
The i-th of the last (n-1) lines contains 2 integers a i,b i (1≤a i,b i≤n).

OutputFor each set, (n-1) integers R 1,R 2,…,R n-1.Sample Input

4
1 2 2 1
1 2
2 3
3 4
5
1 1 2 1 2
1 3
2 3
3 5
4 5

Sample Output

1
2
1
1
1
2
1

Hint

题解:题意就是,给以一颗树n个节点,每个节点有一种颜色,然年后对于n-1条边,如果把一条边截断,让你求两颗子树有多少种相同的颜色,依次输入每一条边的答案。

启发式搜索,分别记录点和边的答案;如果点u和其子树某种颜色的数量已经等于总量了,那么对于该子树外的一部分,就没有该中颜色了,答案-1;如果小于总量,答案+1;

然后更新u节点该颜色的数量即可;

参考代码:

 #include<bits/stdc++.h>
using namespace std;
#define clr(a,val) memset(a,val,sizeof (a))
#define pb push_back
#define fi first
#define se second
typedef long long ll;
const int maxn=1e5+;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-') f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
}
struct Edge{
int to,index,nxt;
} edge[maxn<<];
int n,head[maxn<<],tot;
int col[maxn],sum[maxn],ans[maxn],res[maxn<<];//ans[u]表示u点及子节点的答案, res[edge]表示边的答案
map<int,int> cnt[maxn];//cnt[u][color] 表示u点子树color颜色有多少个节点 inline void Init()
{
clr(head,-);clr(sum,); tot=;
for(int i=;i<=n;++i) cnt[i].clear();
} inline void addedge(int u,int v,int id)
{
edge[tot].to=v;
edge[tot].index=id;
edge[tot].nxt=head[u];
head[u]=tot++;
} inline void dfs(int u,int fa,int id)
{
cnt[u][col[u]]=;
ans[u] = cnt[u][col[u]]<sum[col[u]]?:;
for(int e=head[u];~e;e=edge[e].nxt)
{
int v=edge[e].to;
if(v==fa) continue;
dfs(v,u,edge[e].index);
if(cnt[u].size()<cnt[v].size())
{
swap(cnt[u],cnt[v]);
swap(ans[u],ans[v]);
}
map<int,int>::iterator it;
for(it=cnt[v].begin();it!=cnt[v].end();it++)
{
if(!cnt[u][(*it).fi] && (*it).se<sum[(*it).fi]) ++ans[u];
else if(cnt[u][(*it).fi] && cnt[u][(*it).fi]+(*it).se==sum[(*it).fi]) --ans[u];
cnt[u][(*it).fi]+=(*it).se;//加上子树的数量
}
}
res[id]=ans[u];
} int main()
{
while(~scanf("%d",&n))
{
Init();
for(int i=;i<=n;++i) col[i]=read(),sum[col[i]]++;
for(int i=;i<n;++i)
{
int u=read(),v=read();
addedge(u,v,i);addedge(v,u,i);
}
dfs(,,);
for(int i=;i<n;++i) printf("%d\n",res[i]);
} return ;
}

CSUOJ1811 Tree Intersection (启发式合并)的更多相关文章

  1. csu oj 1811: Tree Intersection (启发式合并)

    题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1811 给你一棵树,每个节点有一个颜色.问删除一条边形成两棵子树,两棵子树有多少种颜色是有 ...

  2. dsu on tree 树上启发式合并 学习笔记

    近几天跟着dreagonm大佬学习了\(dsu\ on\ tree\),来总结一下: \(dsu\ on\ tree\),也就是树上启发式合并,是用来处理一类离线的树上询问问题(比如子树内的颜色种数) ...

  3. dsu on tree[树上启发式合并学习笔记]

    dsu on tree 本质上是一个 启发式合并 复杂度 \(O(n\log n)\) 不支持修改 只能支持子树统计 不能支持链上统计- 先跑一遍树剖的dfs1 搞出来轻重儿子- 求每个节点的子树上有 ...

  4. dsu on tree (树上启发式合并) 详解

    一直都没出过算法详解,昨天心血来潮想写一篇,于是 dsu on tree 它来了 1.前置技能 1.链式前向星(vector 建图) 2.dfs 建树 3.剖分轻重链,轻重儿子 重儿子 一个结点的所有 ...

  5. AGC 014E.Blue and Red Tree(思路 启发式合并)

    题目链接 \(Description\) 给定两棵\(n\)个点的树,分别是由\(n-1\)条蓝边和\(n-1\)条红边组成的树.求\(n-1\)次操作后,能否把蓝树变成红树. 每次操作是,选择当前树 ...

  6. dsu on tree(树上启发式合并)

    简介 对于一颗静态树,O(nlogn)时间内处理子树的统计问题.是一种优雅的暴力. 算法思想 很显然,朴素做法下,对于每颗子树对其进行统计的时间复杂度是平方级别的.考虑对树进行一个重链剖分.虽然都基于 ...

  7. CSU 1811: Tree Intersection(线段树启发式合并||map启发式合并)

    http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1811 题意:给出一棵树,每一个结点有一个颜色,然后依次删除树边,问每次删除树边之后,分开的两个 ...

  8. codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(启发式合并)

    codeforces 741D Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths 题意 给出一棵树,每条边上有一个字符,字符集大小只 ...

  9. 树上启发式合并(dsu on tree)学习笔记

    有丶难,学到自闭 参考的文章: zcysky:[学习笔记]dsu on tree Arpa:[Tutorial] Sack (dsu on tree) 先康一康模板题吧:CF 600E($Lomsat ...

随机推荐

  1. vue的相关知识

    一.DOM vs 函数库 vs框架 DOM:  API繁琐 函数库:JQuery对DOM的每个步骤的API进行一对一的简化,但并没有改变DOM做事的步骤和方法. 框架:一个包含部分已经实现的功能的半成 ...

  2. 201871010114-李岩松《面向对象程序设计(java)》第七周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  3. 【原创】使用批处理脚本生成包并自动上传到nuget

    Hello 大家好,我是TANZAME,我们又见面了. NuGet 是什么这里就不再重复啰嗦,园子里一搜一大把.今天要跟大家分享的是,在日常开发过程中如何统一管理我们的包,如何通过批处理脚本生成包并自 ...

  4. 腾讯Techo开发者大会PPT分享

    腾讯云年度的开发者大会已经落幕,大会包括1场前沿技术主峰会,18个技术专场,150位海内外技术专家,28个互动展区,8场动手实验室,23小时小程序云开发极限编程,1场数据库诊断大赛. 内容上涵盖了最新 ...

  5. C#查看已下载文件大小和扩展名

    FileInfo fi = new FileInfo(fullfile);//fullfile文件路径 ong Size = fi.Length;//查看已下载文件的大小 C# 获取文件名及扩展名 s ...

  6. Nebula 架构剖析系列(二)图数据库的查询引擎设计

    摘要 上文(存储篇)说到数据库重要的两部分为存储和计算,本篇内容为你解读图数据库 Nebula 在查询引擎 Query Engine 方面的设计实践. 在 Nebula 中,Query Engine ...

  7. Jquery 处理返回的 Json 数组

    Jquery 处理返回的 Json 数组 <script> for (var i = 0; i < photos.length; ++ i) { console.log(photos ...

  8. 力扣(LeetCode)寻找数组的中心索引 个人题解

    给定一个整数类型的数组 nums,请编写一个能够返回数组“中心索引”的方法. 我们是这样定义数组中心索引的:数组中心索引的左侧所有元素相加的和等于右侧所有元素相加的和. 如果数组不存在中心索引,那么我 ...

  9. python接口自动化--Excel

    1.操作步骤: (1)安装python官方Excel库-->xlrd (2)获取Excel文件位置并读取 (3)读取sheet (4)读取指定rows和cols内容 2.示例代码 # -*- c ...

  10. UML分析AsyncDisplayKit框架-ASMuplexImageNode异步下载时序图。

    PS:博客园图片服务器不正常工作,数据上传后服务器返回http500,园方迟迟还没解决. 我从2016-01-18 05:52向园方反馈问题-请问博客园的图片服务器有在正常运行吗,至此时2016-01 ...