题目大意:给定一棵 N 个节点的有根树,1 号节点是树的根节点,每个节点有一个颜色。求对于每个节点来说,能够支配整棵子树的颜色之和是多少。支配的定义为对于以 i 为根的子树,该颜色出现的次数不小于任何其他颜色出现的次数。

题解:学会了 dsu on tree。

树上启发式合并算法是一种对暴力的优化算法。对于暴力算法来说,直接遍历每个节点,再遍历该节点对应的子树寻找答案,时间复杂度显然为 \(O(n^2)\)。考虑进行优化,显然对于父节点来说,遍历到的最后一棵子树的贡献可以不用消去,直接加在父节点对应的子树上即可。根据这条性质,每次都选择 i 的重儿子进行直接累加答案贡献,重儿子的定义和求法与树剖中重儿子相同。可以看出对于树上每个节点,在统计答案的时候仅仅遍历了子树内的所有轻边,即:重儿子对应的子树再合并时不需要再次遍历。从全局的角度来说,对于第 i 个节点为根的子树,子树在统计答案时被遍历的次数和该节点到根节点路径上的轻边个数成正比。一共只有 \(O(logn)\) 条轻边,因此,遍历 n 个节点的时间复杂度上界为 \(O(nlogn)\)。

代码如下

#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) x.begin(),x.end()
#define cls(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const int dx[]={0,1,0,-1};
const int dy[]={1,0,-1,0};
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
const int maxn=1e5+10;
const double eps=1e-6;
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
inline ll sqr(ll x){return x*x;}
inline ll fpow(ll a,ll b,ll c){ll ret=1%c;for(;b;b>>=1,a=a*a%c)if(b&1)ret=ret*a%c;return ret;}
inline ll read(){
ll x=0,f=1;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch));
do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch));
return f*x;
}
/*------------------------------------------------------------*/ vector<int> G[maxn];
int size[maxn],son[maxn];
int n,cor[maxn],cnt[maxn];
bool skip[maxn];
ll mx,now,ans[maxn]; void getsize(int u,int fa){
size[u]=1;
for(auto v:G[u]){
if(v==fa)continue;
getsize(v,u);
if(size[v]>size[son[u]])son[u]=v;
size[u]+=size[v];
}
}
void add(int u,int fa,int val){
cnt[cor[u]]+=val;
if(val>0){
if(cnt[cor[u]]>mx)now=cor[u],mx=cnt[cor[u]];
else if(cnt[cor[u]]==mx)now+=cor[u];
}
for(auto v:G[u]){
if(v==fa||skip[v])continue;
add(v,u,val);
}
}
void dfs(int u,int fa,bool keep){
for(auto v:G[u]){
if(v==fa||v==son[u])continue;
dfs(v,u,0);
}
if(son[u])dfs(son[u],u,1),skip[son[u]]=1;
add(u,fa,1);
ans[u]=now;
if(son[u])skip[son[u]]=0;
if(!keep)add(u,fa,-1),mx=now=0;
} void read_and_parse(){
n=read();
for(int i=1;i<=n;i++)cor[i]=read();
for(int i=1,x,y;i<n;i++){
x=read(),y=read();
G[x].pb(y),G[y].pb(x);
}
}
void solve(){
getsize(1,0);
dfs(1,0,1);
for(int i=1;i<=n;i++)printf("%lld%c",ans[i],i==n?'\n':' ');
}
int main(){
read_and_parse();
solve();
return 0;
}

【CF600E】Lomsat gelral的更多相关文章

  1. 【CF600E】Lomsat gelral(dsu on tree)

    [CF600E]Lomsat gelral(dsu on tree) 题面 洛谷 CF题面自己去找找吧. 题解 \(dsu\ on\ tree\)板子题 其实就是做子树询问的一个较快的方法. 对于子树 ...

  2. 【CF600E】 Lomsat gelral

    CF600E Lomsat gelral Solution 考虑一下子树的问题,我们可以把一棵树的dfn序搞出来,那么子树就是序列上的一段连续的区间. 然后就可以莫队飞速求解了. 但是这题还有\(\T ...

  3. 【CF600E】Lomsat gelral——树上启发式合并

    (题面来自luogu) 题意翻译 一棵树有n个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. ci <= n <= 1e5 裸题.统计时先扫一遍得到出 ...

  4. 【CF600E】Lomset gelral 题解(树上启发式合并)

    题目链接 题目大意:给出一颗含有$n$个结点的树,每个节点有一个颜色.求树中每个子树最多的颜色的编号和. ------------------------- 树上启发式合并(dsu on tree). ...

  5. 「CF600E」Lomsat gelral

    传送门 Luogu 解题思路 线段树合并板子题(也可以 dsu on the tree) 好像没什么好讲的,就是要注意开 long long . 细节注意事项 咕咕咕 参考代码 #include &l ...

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

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

  7. 【Codeforces】600E. Lomsat gelral

    Codeforces 600E. Lomsat gelral 学习了一下dsu on tree 所以为啥是dsu而不是dfs on tree??? 这道题先把这棵树轻重链剖分了,然后先处理轻儿子,处理 ...

  8. CF600E Lomsat gelral 和 CF741D Dokhtar-kosh paths

    Lomsat gelral 一棵以\(1\)为根的树有\(n\)个结点,每个结点都有一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号(若有数量一样的,则求编号和). \(n \le 10^ ...

  9. 【主席树启发式合并】【P3302】[SDOI2013]森林

    Description 给定一个 \(n\) 个节点的森林,有 \(Q\) 次操作,每次要么将森林中某两点联通,保证操作后还是个森林,要么查询两点间权值第 \(k\) 小,保证两点联通.强制在线. L ...

随机推荐

  1. java中级——集合框架【4】-Collections

    Collections 首先我们要知道Collections是一个类,容器的工具类,就如同Arrays是数组的工具类 反转 reverse 使List中的数据发生发转 package cn.jse.c ...

  2. python爬虫之git的使用

    一.简单认识: 1.初始化文件夹为版本控制文件夹,首先建立一个文件夹,进入这个文件夹以后输入git init初始化这个文件夹. 2.Git几种位置概念 1.本地代码:本地更改完代码以后,虽然是存放在g ...

  3. Window下通过SecureCRT的SSH2跳转到另一台Linux服务器

    我工作中的示例: 先登录192.168.2.145 Your password will be expired in 200 days.Welcome to Baoleiji System.Last ...

  4. CentOS7下Nginx搭建反向代理,并使用redis保存session

    1.启动两个tomcat,端口分别为8080,8081 2.配置nginx,vim /usr/local/nginx/conf/nginx.conf 添加如下配置: 3.启动nginx或热加载 启动: ...

  5. StringBuilder与String有哪些区别?

    System.String具备不可修改性,在程序中这样的特性容易产生性能上的问题.针对这个问题.NET提供的StringBuilder类可以解决类似的问题. String 和 StringBuilde ...

  6. Ajax的post表单,不在url后接一大串参数键值对的方法

    $('#loginForm').on('submit',function (ev) { //阻止表单参数附在url后面 ev.stopPropagation(); ev.preventDefault( ...

  7. js中的异常处理

    js中的异常处理语句有两个,一个是try……catch……,一个是throw. try……catch用于语法错误,错误有name和message两个属性.throw用于逻辑错误. 对于逻辑错误,js是 ...

  8. ASP.NET Core 2.0 Cookie Authentication

    using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Builder; using Microso ...

  9. codeforces263B

    Squares CodeForces - 263B Vasya has found a piece of paper with a coordinate system written on it. T ...

  10. Ontology

    本体网络(Ontology) 新一代分布式信任链网 在开始了解项目之前,让我们先看一段“第一财经”频道关于“本体网络”的介绍: 项目介绍 1摘要 类型  提供不同分布式应用场景的开放基础模块,构建跨链 ...