题目链接: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. linux内核的双链表list_head、散列表hlist_head

    一.双链表list_head 1.基本概念 linux内核提供的标准链表可用于将任何类型的数据结构彼此链接起来. 不是数据内嵌到链表中,而是把链表内嵌到数据对象中. 即:加入链表的数据结构必须包含一个 ...

  2. [转载]C#中使用正则表达式验证电话号码、手机号、身份证号、数字和邮编

    原文出处:https://www.cnblogs.com/wuhuisheng/archive/2011/03/23/1992652.html 验证电话号码的主要代码如下: public bool I ...

  3. python 3.7 方向键乱码

    原因是缺少安装包libreadline-dev 第一步安装libreadline-dev包:sudo apt-get install libreadline-dev(centos安装:yum -y i ...

  4. django 上传文件及反馈信息

    from django.shortcuts import render,HttpResponse from django.views import View from Fiskars.models i ...

  5. gnats配置文件

    尽管NATS可以无配置的运行,但也可以使用配置文件配置NATS服务器 1. 配置项包括 客户端监听器端口 Client listening port HTTP监听器端口 HTTP monitoring ...

  6. Spring Boot 整合Mybatis非starter时,mapper一直无法注入解决

    本来呢,直接使用mybatis-spring-boot-starter还是挺好的,但是我们系统比较复杂,有多个数据源,其中一个平台自己的数据源,另外一些是动态配置出来的,两者完全没有关系.所以直接使用 ...

  7. python 爬取历史天气

    python 爬取历史天气 官网:http://lishi.tianqi.com/luozhuangqu/201802.html # encoding:utf-8 import requests fr ...

  8. Java线程池详解,看这篇就够了!

    构造一个线程池为什么需要几个参数?如果避免线程池出现OOM?Runnable和Callable的区别是什么?本文将对这些问题一一解答,同时还将给出使用线程池的常见场景和代码片段. 基础知识 Execu ...

  9. Summarization of Tech Interviews

    Summarization of Tech Interviews(技术面试总结) 手心网(2015) Q1. 解释一下 TCP/IP 协议之滑动窗口? 滑动窗口协议的维基:https://en.wik ...

  10. ARM 架构、ARM7、ARM9、STM32、Cortex M3 M4 、51、AVR 之间有什么区别和联系?(转载自知乎)

    ARM架构:  由英国ARM公司设计的一系列32位的RISC微处理器架构总称,现有ARMv1~ARMv8种类. ARM7:       一类采用ARMv3或ARMv4架构的,使用冯诺依曼结构的内核. ...