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. java VS c#,异同点

    因工作安排,后期需要维护一个java项目.所以稍微熟悉下java,开此篇记录下java与c#的区别点,方便增强自己学习效果.肯定是不全的,可能是有错的,欢迎批评指正. 一.关键字 描述 C# Java ...

  2. Python 基础 面向对象之二 三大特性

    Python 基础 面向对象之二 三大特性 上一篇主要介绍了Python中,面向对象的类和对象的定义及实例的简单应用,本篇继续接着上篇来谈,在这一篇中我们重点要谈及的内容有:Python 类的成员.成 ...

  3. SpringMVC错误:Failed to read candidate component class:file... ...

    Failed to read candidate component class:file错误分析和处理 org.springframework.beans.factory.BeanDefinitio ...

  4. suseoj 1207: 大整数的乘法(java, 大数相乘, C/C++, 大数相乘)

    1207: 大整数的乘法 时间限制: 1 Sec  内存限制: 128 MB提交: 7  解决: 2[提交][状态][讨论版][命题人:liyuansong] 题目描述 求两个不超过200位的非负整数 ...

  5. 领扣(LeetCode)翻转二叉树 个人题解

    翻转一棵二叉树. 示例: 输入: 4 / \ 2 7 / \ / \ 1 3 6 9 输出: 4 / \ 7 2 / \ / \ 9 6 3 1 备注:这个问题是受到 Max Howell的 原问题  ...

  6. 使用图数据库 Nebula Graph 数据导入快速体验知识图谱 OwnThink

    前言 本文由 Nebula Graph 实习生@王杰贡献. 最近 @Yener 开源了史上最大规模的中文知识图谱--OwnThink(链接:https://github.com/ownthink/Kn ...

  7. C# 未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”

    “Microsoft.Jet.OLEDB.4.0” 是数据库接口驱动,用来连接数据库的,一般多用于连Access和Excel.我在在winform开发时,在本地运行没有问题,可是部署到另一台服务器上就 ...

  8. k8s 获取 Pod ip 添加到环境变量

    0x00 事件 有一个需要将 Pod 自身的 ip 地址添加到环境变量的需求,可以在 yaml 文件的 env 中这样设置: env: - name: POD_OWN_IP_ADDRESS value ...

  9. cnpm镜像安装

    npm install -g cnpm --registry=https://registry.npm.taobao.org

  10. .NET高级特性-Emit(2.2)属性

    关于Emit的博客已经进入第四篇,在读本篇博文之前,我希望读者能先仔细回顾博主之前所编写的关于Emit的博文,从该篇博文开始,我们就可以真正的使用Emit,并把知识转化为实战,我也会把之前的博文链接放 ...