题目链接:http://codeforces.com/problemset/problem/600/E


n个点的有根树,以1为根,每个点有一种颜色。我们称一种颜色占领了一个子树当且仅当没有其他颜色在这个子树中出现得比它多。求占领每个子树的所有颜色之和

我们都知道可以$BST$启发式合并从而完美${O(nlogn^{2})}$,这太丑陋了。

那么$Dsu~~on~~tree$是在干啥呢?

找出树中每一个节点的重儿子,统计答案的时候优先进入每一个点的所有轻儿子,之后再进入重儿子,目的是保留重儿子所在子树的信息。

处理完当前点的所有儿子的子树之后开始处理自己。

先统计以当前点为根的子树不经过重儿子的所有点的影响${O(size[x]-size[hson[x]])}$

如果这个点是轻儿子则需要暴力删除这棵子树所带来的影响${O(size[x])}$,这也正是先进入轻儿子的原因,可以保留重儿子的信息。

考虑复杂度为什么正确:

  不妨想想一个点被反复计算了多少次?是不是${O(这个点到根的轻边条树)}$,这个东西是${O(logn)}$级别的。

最终复杂度:${O(nlogn)}$


 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<cmath>
#include<cstring>
using namespace std;
#define maxn 300100
#define llg long long
#define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
llg n,m,hson[maxn],size[maxn],ans[maxn],c[maxn],cnt[maxn],sum,mx,S;
vector<llg>a[maxn]; inline llg getint()
{
llg w=,q=; char c=getchar();
while((c<'' || c>'') && c!='-') c=getchar(); if(c=='-') q=,c=getchar();
while (c>='' && c<='') w=w*+c-'', c=getchar(); return q ? -w : w;
} void init()
{
llg x,y;
cin>>n;
for (llg i=;i<=n;i++) c[i]=getint();
for (llg i=;i<n;i++)
{
x=getint(),y=getint();
a[x].push_back(y),a[y].push_back(x);
}
} void find_hson(llg x,llg fa)
{
size[x]=;
llg w=a[x].size(),v;
for (llg i=;i<w;i++)
{
v=a[x][i];
if (v==fa) continue;
find_hson(v,x);
size[x]+=size[v];
if (size[v]>size[hson[x]]) hson[x]=v;
}
} void calc(llg x,llg fa,llg val)
{
cnt[c[x]]+=val;
if (cnt[c[x]]>mx) sum=c[x],mx=cnt[c[x]];
else
{
if (cnt[c[x]]==mx) sum+=c[x];
}
llg w=a[x].size(),v;
for (llg i=;i<w;i++)
{
v=a[x][i];
if (v==fa || v==S) continue;
calc(v,x,val);
}
} void dfs(llg x,llg fa,llg t)
{
llg w=a[x].size(),v;
for (llg i=;i<w;i++)
{
v=a[x][i];
if (v==fa || v==hson[x]) continue;
dfs(v,x,-);
}
if (hson[x]) dfs(hson[x],x,),S=hson[x];
calc(x,fa,); S=;
ans[x]=sum;
if (t==-) calc(x,fa,-),mx=sum=;
} int main()
{
yyj("tree");
init();
find_hson(,);
dfs(,,);
for (llg i=;i<=n;i++) printf("%lld ",ans[i]);
return ;
}

Codeforces 600E. Lomsat gelral(Dsu on tree学习)的更多相关文章

  1. Codeforces.600E.Lomsat gelral(dsu on tree)

    题目链接 dsu on tree详见这. \(Description\) 给定一棵树.求以每个点为根的子树中,出现次数最多的颜色的和. \(Solution\) dsu on tree模板题. 用\( ...

  2. CF 600E. Lomsat gelral(dsu on tree)

    解题思路 \(dsu\) \(on\) \(tree\)的模板题.暴力而优雅的算法,轻儿子的信息暴力清空,重儿子的信息保留,时间复杂度\(O(nlogn)\) 代码 #include<iostr ...

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

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

  4. Codeforces 600E Lomsat gelral(dsu on tree)

    dsu on tree板子题.这个trick保证均摊O(nlogn)的复杂度,要求资瓷O(1)将一个元素插入集合,清空集合时每个元素O(1)删除.(当然log的话就变成log^2了) 具体的,每次先遍 ...

  5. Codeforces 600E - Lomsat gelral 「$Dsu \ on \ tree$模板」

    With $Dsu \ on \ tree$ we can answer queries of this type: How many vertices in the subtree of verte ...

  6. 【CodeForces】600 E. Lomsat gelral (dsu on tree)

    [题目]E. Lomsat gelral [题意]给定n个点的树,1为根,每个点有一种颜色ci,一种颜色占领一棵子树当且仅当子树内没有颜色的出现次数超过它,求n个答案——每棵子树的占领颜色的编号和Σc ...

  7. codeforces 600E Lomsat gelral

    题面:codeforces600E 学习一下$dsu \ on \ tree$.. 这个东西可以处理很多无修改子树问题,复杂度通常为$O(nlogn)$. 主要操作是:我们先把整棵树链剖一下,然后每次 ...

  8. cf600E. Lomsat gelral(dsu on tree)

    题意 题目链接 给出一个树,求出每个节点的子树中出现次数最多的颜色的编号和 Sol dsu on tree的裸题. 一会儿好好总结总结qwq #include<bits/stdc++.h> ...

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

    题目链接 Lomsat gelral 占坑……等深入理解了再来补题解…… #include <bits/stdc++.h> using namespace std; #define rep ...

随机推荐

  1. 今天2.4寸tft触摸屏到手--刷屏驱动小结

    2010-04-29 21:28:00 根据给的51程序改成了iccavr,结果改错了2处.导致我找原因找了n久.不过也是一件好事,让我对80i更加熟悉了. 通过protues的逻辑分析仪,找到了问题 ...

  2. Codeforce 835A - Key races

    Two boys decided to compete in text typing on the site "Key races". During the competition ...

  3. Django框架----logging配置

    我写Django项目常用的logging配置.(追加在setting.py文件中) LOGGING = { 'version': 1, 'disable_existing_loggers': Fals ...

  4. MySql安装和基本管理

    一.什么是数据库? mysql就是一个基于socket编写的C/S架构的软件 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下公司.MySQL 最流 ...

  5. 网上搜到的权限系统demo

    网上搜到的权限系统demo http://www.sojson.com/shiro

  6. P5290 [十二省联考2019]春节十二响(堆+启发式合并)

    P5290 [十二省联考2019]春节十二响 从特殊到一般 我们先看链的情况. 我们把点$1$左右的两条子链分别扔入堆里 每次取出两个堆的最大值,把答案累加上更大的那个(另一堆为空则直接加上去). 那 ...

  7. bzoj1663: [Usaco2006 Open]赶集

    Description Every year, Farmer John loves to attend the county fair. The fair has N booths (1 <= ...

  8. Java中的Volatile和synchronized的区别

    Synchronized和Volatile四个不同点: 1.粒度不同,前者锁对象和类 ,后者针对变量2.syn阻塞,volatile线程不阻塞3.syn保证三大特性,volatile不保证原子性4.s ...

  9. Linux上的oracle巡检脚本

    修改自大神博客:http://www.cnblogs.com/jyzhao/p/5364049.html 脚本巡检的优化:自动化,节省时间. 脚本需加强:巡检结果中有大量的sqlplus连接信息,后期 ...

  10. 如何写好接口(php写app移动端接口示例)

    原文链接:https://blog.csdn.net/xwh670570759/article/details/52130585?utm_source=blogxgwz0