题面:codeforces600E

学习一下$dsu \ on \ tree$。。

这个东西可以处理很多无修改子树问题,复杂度通常为$O(nlogn)$。

主要操作是:我们先把整棵树链剖一下,然后每次先递归轻儿子,再递归重儿子。

对于每棵子树,我们暴力加入整棵子树的贡献。如果是重儿子的子树则另外处理:加入贡献时不考虑加重儿子所在的子树,而在消除贡献时也不消除重儿子的子树,直到它成为某个点的轻儿子的子树的一部分时再消除贡献。

复杂度:因为每个轻儿子最多被加入$O(logn)$次(递归轻儿子时$size$至少$/2$),每条重链最多只会被加入$O(logn)$次,所以复杂度是$O(nlogn)$的。

说得有点玄学,还是看看代码吧。。

 //It is made by wfj_2048~
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define inf (1<<30)
#define N (200010)
#define il inline
#define RG register
#define ll long long using namespace std; struct edge{ int nt,to; }g[N<<]; int head[N],col[N],son[N],sz[N],c[N],n,num,Mx,flag;
ll ans[N],Sum; il int gi(){
RG int x=,q=; RG char ch=getchar();
while ((ch<'' || ch>'') && ch!='-') ch=getchar();
if (ch=='-') q=-,ch=getchar();
while (ch>='' && ch<='') x=x*+ch-,ch=getchar();
return q*x;
} il void insert(RG int from,RG int to){
g[++num]=(edge){head[from],to},head[from]=num; return;
} il void dfs1(RG int x,RG int p){
sz[x]=; RG int v;
for (RG int i=head[x];i;i=g[i].nt){
v=g[i].to; if (v==p) continue;
dfs1(v,x),sz[x]+=sz[v];
if (sz[son[x]]<=sz[v]) son[x]=v;
}
return;
} il void add(RG int x,RG int p,RG int val){
col[c[x]]+=val; RG int v;
if (Mx<col[c[x]]) Mx=col[c[x]],Sum=c[x];
else if (Mx==col[c[x]]) Sum+=c[x];
for (RG int i=head[x];i;i=g[i].nt){
v=g[i].to; if (v==p || v==flag) continue;
add(v,x,val);
}
return;
} il void dfs2(RG int x,RG int p,RG int fg){
RG int v;
for (RG int i=head[x];i;i=g[i].nt){
v=g[i].to; if (v!=p && v!=son[x]) dfs2(v,x,);
}
if (son[x]) dfs2(son[x],x,),flag=son[x];
add(x,p,),flag=,ans[x]=Sum;
if (fg) add(x,p,-),Mx=Sum=; return;
} int main(){
#ifndef ONLINE_JUDGE
freopen("600E.in","r",stdin);
freopen("600E.out","w",stdout);
#endif
n=gi();
for (RG int i=;i<=n;++i) c[i]=gi();
for (RG int i=,u,v;i<n;++i)
u=gi(),v=gi(),insert(u,v),insert(v,u);
dfs1(,),dfs2(,,);
for (RG int i=;i<=n;++i) printf("%I64d ",ans[i]);
return ;
}

codeforces 600E Lomsat gelral的更多相关文章

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

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

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

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

  3. Codeforces 600E. Lomsat gelral(Dsu on tree学习)

    题目链接:http://codeforces.com/problemset/problem/600/E n个点的有根树,以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 启发式合并

    题目链接 给一颗树, 每个节点有初始的颜色值. 1为根节点.定义一个节点的值为, 它的子树中出现最多的颜色的值, 如果有多种颜色出现的次数相同, 那么值为所有颜色的值的和. 每一个叶子节点是一个map ...

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

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

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

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

  8. 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 ...

  9. 【Codeforces】600E. Lomsat gelral

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

随机推荐

  1. python3 enumerate()函数笔记

    d={"A":"a","B":"b","C":"c","D" ...

  2. 企业生产环境不同业务linux系统分区方案

    转自:http://edu.51cto.com/lession/id-11842.html

  3. ubuntu 修改hostname

    1.sudo gedit /etc/hostname 2. 修改成你的新名字,例如 SS1 3. 保存,退出 3. sudo gedit /etc/hosts 4修改成心的名字 SS1 5. 保存,退 ...

  4. c++中 重载 覆盖 隐藏的区别 附加 mutable笔记

    成员函数被重载的特征有: 1) 相同的范围(在同一个类中): //2) 函数名字相同: 3) 参数不同: 4) virtual关键字可有可无. 覆盖的特征有: 1) 不同的范围(分别位于派生类与基类) ...

  5. (转)centOS wget的使用

    摘要:CentOS wget是一个从网络上自动下载文件的自由工具.它支持HTTP,HTTPS和FTP协议,可以使用HTTP代理. 所谓的自动下载是指,CentOS wget可以在用户退出系统的之后在后 ...

  6. Kure讲HTML_HTML界面结构

    1.HTML界面结构: 通常通过html开发的网页,它有一个自己固定的书写格式(类似于写信的时候也有固定的格式) <!-- DOCTYPE用来告诉浏览器用当前html文档是用html的哪个版本编 ...

  7. git 摘要

    git使用摘记 git冲突的问题主要是在修改的部分而不是添加的部分, 如果merge的文件在同一个位置有不同的信息则git会报错 git push origin中的origin表示的是远程的仓库名为o ...

  8. pacman usage

    pacman使用 安装了系统时候, 应该立马使用pacman-mirrors -c China更新源, 再使用pacman -Syyn更新系统 编辑/etc/pacman.conf添加 [archli ...

  9. C# 使用消息队列,包括远程访问

    转:https://www.cnblogs.com/80X86/p/5557801.html 功能需求,用到了队列,用的时候出了很多问题,现在总结一下,希望能对有需要的人提供帮助. 我的需求很简单,就 ...

  10. jdk安装完为什么会有两个JRE?

    jdk安装完为什么会有两个JRE? 之所以需要两套 jre ,是因为可以分担工作:当用户只需要执行 java 的程序时,那么 c:\program files\java\jre 下的 jre 就 ok ...