启发式合并最重要的思想就是指的是每次将小集合拷贝合并至大集合。
考虑每个元素的合并开销。对于合并次数最多的那个元素来说,它每合并一次,所在集合的规模扩大两倍,最多只会合并 logN 次,因而对于所有元素,至多插入set中NlogN次,时间复杂度就有上限 O(N∗logN∗logN)

现在主要是dsu on tree,它用来解决这样一类问题:统计树上一个节点的子树中具有某种特征的节点数。 基本上就是树上子树的统计问题。

但是dsu on tree也有一定的局限性:1.只能支持子树查询;2.不支持修改修改。

看例题来说:

D - Lomsat gelralCodeForces - 600E

You are given a rooted tree with root in vertex 1. Each vertex is coloured in some colour.

Let's call colour c dominating in the subtree of vertex v if there are no other colours that appear in the subtree of vertex v more times than colour c. So it's possible that two or more colours will be dominating in the subtree of some vertex.

The subtree of vertex v is the vertex v and all other vertices that contains vertex v in each path to the root.

For each vertex v find the sum of all dominating colours in the subtree of vertex v.

Input

The first line contains integer n (1 ≤ n ≤ 105) — the number of vertices in the tree.

The second line contains n integers ci (1 ≤ ci ≤ n), ci — the colour of the i-th vertex.

Each of the next n - 1 lines contains two integers xj, yj (1 ≤ xj, yj ≤ n) — the edge of the tree. The first vertex is the root of the tree.

Output

Print n integers — the sums of dominating colours for each vertex.

Examples

Input
4
1 2 3 4
1 2
2 3
2 4
Output
10 9 3 4
Input
15
1 2 3 1 2 3 3 1 1 3 2 2 1 2 3
1 2
1 3
1 4
1 14
1 15
2 5
2 6
2 7
3 8
3 9
3 10
4 11
4 12
4 13
Output
6 5 4 3 2 3 3 1 1 3 2 2 1 2 3

题意:给定一个 n 个节点的树,对于每个子树,输出子树中出现次数最多的节点编号之和。(次数最多的编号有多个节点都要统计进去)。 
想法:最初的想法是对于每个点都跑一遍,暴力跑每个点的子树,然后记录下来答案,然后清空数组跑下一次,但是这样的话就时间复杂度就非常的高。
所以要优化一下,我们都知道每个点有子树的话,会有一个重子树(就是点相对最多的那颗子树)。所以我们先预处理一下找到所有节点重子树。
然后对于每科子树,我们先跑每颗子树的轻子树,跑完之后再跑重子树。在计算结果的时候,假设某一个点的儿子都已经被dfs过,统计这个点的答案。统计答案的过程中要calc当前这个点的子树,但是只calc它的轻链,重链不做。 
这样的话,就需要在dfs的过程中,如果当前点是它父亲的轻儿子,做完这个点之后就将影响消除;而如果这个点是它父亲的重儿子,则将这个点的影响保留。 
我们看下代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long LL;
const int maxn=1e5+;
int n,m;
int mx,big;
LL sum=;
LL ans[maxn];
int col[maxn],si[maxn],hson[maxn],cnt[maxn];
vector<int>G[maxn]; void findhson(int x,int fa)//找到所有的重儿子
{
si[x]=;
int len=G[x].size();
for(int i=;i<len;i++)
{
int t=G[x][i];
if(t!=fa)
{
findhson(t,x);
si[x]+=si[t];
if(si[t]>si[hson[x]])
hson[x]=t;
}
}
}
void cal(int x,int fa,int val)//计算的过程,就是不断递归求颜色的数量
{
cnt[col[x]]+=val;
if(cnt[col[x]]>mx)
{
sum=col[x];
mx=cnt[col[x]];
}
else if(cnt[col[x]]==mx)
sum+=col[x];
int len=G[x].size();
for(int i=;i<len;i++)
{
int t=G[x][i];
if(t!=fa && t!=big)
cal(t,x,val);
}
}
void dfs(int x,int fa,int flag)//flag作为标记,看是轻子树还是重子树
{
int len=G[x].size();
for(int i=;i<len;i++)//先跑轻子树
{
int t=G[x][i];
if(t!=fa && t!=hson[x])
dfs(t,x,);
}
if(hson[x])//再跑重子树
{
dfs(hson[x],x,);
big=hson[x];
}
cal(x,fa,);
big=;
ans[x]=sum;
if(!flag)//如果是轻子树的话,消除影响
{
cal(x,fa,-);
mx=;sum=;
}
}
int main()
{
sum=;big=;mx=;
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&col[i]);
int x,y;
for(int i=;i<n;i++)//双向边
{
scanf("%d %d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
}
findhson(,);
dfs(,,);
for(int i=;i<=n;i++)
{
if(i==)
printf("%lld",ans[i]);
else
printf(" %lld",ans[i]);
}
printf("\n");
return ;
}
 
 

启发式合并 CodeForces - 600E的更多相关文章

  1. 启发式合并CodeForces - 1009F

    E - Dominant Indices CodeForces - 1009F You are given a rooted undirected tree consisting of nn vert ...

  2. Codeforces 600E - Lomsat gelral(树上启发式合并)

    600E - Lomsat gelral 题意 给出一颗以 1 为根的树,每个点有颜色,如果某个子树上某个颜色出现的次数最多,则认为它在这课子树有支配地位,一颗子树上,可能有多个有支配的地位的颜色,对 ...

  3. Codeforces - 600E 树上启发式合并

    题意:求每一个子树存在最多颜色的颜色代号和(可重复) 本题是离线统计操作,因此可以直接合并重儿子已达到\(O(nlogn)\)的复杂度 PS.不知道什么是启发式合并的可以这样感受一下:进行树链剖分,分 ...

  4. Educational Codeforces Round 2 E. Lomsat gelral 启发式合并map

    E. Lomsat gelral Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/600/prob ...

  5. CodeForces 958F3 Lightsabers (hard) 启发式合并/分治 多项式 FFT

    原文链接http://www.cnblogs.com/zhouzhendong/p/8835443.html 题目传送门 - CodeForces 958F3 题意 有$n$个球,球有$m$种颜色,分 ...

  6. 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 题意 给出一棵树,每条边上有一个字符,字符集大小只 ...

  7. codeforces#1166F. Vicky's Delivery (Service并查集+启发式合并)

    题目链接: https://codeforces.com/contest/1166/problem/F 题意: 给出节点数为$n$,边数为$m$的图,保证每个点对都是互连的 定义彩虹路:这条路经过$k ...

  8. codeforces 600E E. Lomsat gelral (线段树合并)

    codeforces 600E E. Lomsat gelral 传送门:https://codeforces.com/contest/600/problem/E 题意: 给你一颗n个节点的树,树上的 ...

  9. Codeforces 1455G - Forbidden Value(map 启发式合并+DP)

    Codeforces 题面传送门 & 洛谷题面传送门 首先这个 if 与 end 配对的结构显然形成一个树形结构,考虑把这棵树建出来,于是这个程序的结构就变为,对树进行一遍 DFS,到达某个节 ...

随机推荐

  1. 2.jeesite增删改查

    一.准备数据 在数据库中中添加一张表和数据,以mysql为例 SET NAMES utf8; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------- ...

  2. mysql 时间向减写法

    select *  from  (   select  c.OrderNumber ,    c.Name as equipmentName,     a.*,    d.Starttime, d.E ...

  3. Scala入门到精通

    原文出自于: http://my.csdn.net/lovehuangjiaju 感谢! 也感谢,http://m.blog.csdn.net/article/details?id=52233484 ...

  4. 【BZOJ1487】[HNOI2009]无归岛(仙人掌 DP)

    题目: BZOJ1487 分析: 题目中给定的图一定是一棵仙人掌(每条边最多属于一个环),证明如下: 先考虑单独一个岛的情况.第一,一个岛一定是一张「弦图」,即任意一个大小超过 3 的环都至少有 1 ...

  5. Physical Education Lessons Codeforces - 915E

    http://codeforces.com/problemset/problem/915/E 大概有几种思路: 1.动态开点线段树+标记下传 #1.1标记永久化:想了一会没想出来 1.2可以先扫一遍询 ...

  6. 找规律/贪心 Codeforces Round #310 (Div. 2) A. Case of the Zeros and Ones

    题目传送门 /* 找规律/贪心:ans = n - 01匹配的总数,水 */ #include <cstdio> #include <iostream> #include &l ...

  7. 选择排序 分类: 算法 c/c++ 2014-10-10 20:32 509人阅读 评论(0) 收藏

    选择排序(假设递增排序) 每次选取从当前结点到末尾结点中最小的一个与当前结点交换,每一轮固定一个元素位置. 时间复杂度O(n^2),空间复杂度O(1).下面的示例代码以带头结点的链表为存储结构: #i ...

  8. Xcode7 使用AFNetWorking 报错 添加Security.framework

    Undefined symbols for architecture x86_64: "_SecCertificateCopyData", referenced from: _AF ...

  9. windows下Python的安装,以及IDLE的使用

    一.Python的下载安装 (1)python的windows安装包可以从https://www.python.org 网址中下载,可以下载3.4版本的或者2.7版本的.(2)下载后直接运行即可.然后 ...

  10. vijos P1426兴奋剂检查 多维费用背包问题的hash

    https://vijos.org/p/1426 这是个好题,容易想到用dp[i][v1][v2][v3][v4][v5]表示在前i个物品中,各种东西的容量是那个的时候,能产生的最大价值. 时间不会T ...