题意:求每一个子树存在最多颜色的颜色代号和(可重复)

本题是离线统计操作,因此可以直接合并重儿子已达到\(O(nlogn)\)的复杂度

PS.不知道什么是启发式合并的可以这样感受一下:进行树链剖分,分出重儿子和轻儿子,每次离线dfs时保留重儿子得出的贡献,清除轻儿子的贡献并重新遍历

(反正是一种取代树上莫队的简单粗暴玩意,但是效率贼tm好)

唯一不解的小细节是似乎我在轻儿子的撤销操作中更新tmp存在问题,改了另一种写法就A了

想不出反例,求指教

Update:看出来了,是我傻缺..

#include<bits/stdc++.h>
#define rep(i,j,k) for(register int i=j;i<=k;i++)
#define rrep(i,j,k) for(register int i=j;i>=k;i--)
#define erep(i,u) for(register int i=head[u];~i;i=nxt[i])
#define print(a) printf("%lld",(ll)(a))
#define println(a) printf("%lld\n",(ll)(a))
#define printbk(a) printf("%lld ",(ll)(a))
using namespace std;
const int MAXN = 1e5+11;
typedef long long ll;
ll read(){
ll x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int to[MAXN<<1],nxt[MAXN<<1],head[MAXN],tot;
int CLOCK,size[MAXN],st[MAXN],ed[MAXN],pre[MAXN];
int cntVal[MAXN],cntNum[MAXN],tmp,n;
bool vis[MAXN];
ll sum[MAXN],ans[MAXN],c[MAXN];
void init(){
memset(head,-1,sizeof head);
memset(cntVal,0,sizeof cntVal);
memset(cntNum,0,sizeof cntNum);
memset(sum,0,sizeof sum);
memset(vis,0,sizeof vis);
tmp=0;tot=0;CLOCK=0;
}
void add(int u,int v){
to[tot]=v;nxt[tot]=head[u];head[u]=tot++;
swap(u,v);
to[tot]=v;nxt[tot]=head[u];head[u]=tot++;
}
void prepare(int u,int p){
size[u]=1;
st[u]=++CLOCK;pre[CLOCK]=u;
erep(i,u){
int v=to[i];
if(v==p)continue;
prepare(v,u);
size[u]+=size[v];
}
ed[u]=CLOCK;
}
void dfs(int u,int p,bool keep){
int mx=0,son=-1;
erep(i,u){
int v=to[i];
if(v==p)continue;
if(size[v]>mx){
mx=size[v];
son=v;
}
}
erep(i,u){
int v=to[i];
if(v==p)continue;
if(v==son) continue;
dfs(v,u,0);
}
if(~son) dfs(son,u,1);
erep(i,u){
int v=to[i];
if(v==p)continue;
if(v==son)continue;
rep(j,st[v],ed[v]){
int o=pre[j];
sum[cntVal[c[o]]]-=c[o];
cntNum[cntVal[c[o]]]--;
cntVal[c[o]]++;
cntNum[cntVal[c[o]]]++;
sum[cntVal[c[o]]]+=c[o];
if(tmp<cntVal[c[o]]) tmp=cntVal[c[o]];
}
}
sum[cntVal[c[u]]]-=c[u];
cntNum[cntVal[c[u]]]--;
cntVal[c[u]]++;
cntNum[cntVal[c[u]]]++;
sum[cntVal[c[u]]]+=c[u];
if(tmp<cntVal[c[u]]) tmp=cntVal[c[u]]; ans[u]=sum[tmp]; if(!keep){
rep(i,st[u],ed[u]){
int v=pre[i];
sum[cntVal[c[v]]]-=c[v];
cntNum[cntVal[c[v]]]--;
//if(tmp==cntVal[c[v]]&&cntNum[cntVal[c[v]]]==0) tmp--;
cntVal[c[v]]--;
cntNum[cntVal[c[v]]]++;
sum[cntVal[c[v]]]+=c[v];
if(cntNum[tmp]==0) tmp--;
}
}
}
int main(){
while(cin>>n){
init();
rep(i,1,n) c[i]=read();
rep(i,1,n) if(!vis[c[i]]){
sum[0]+=c[i];
cntNum[0]++;
vis[c[i]]=1;
}
rep(i,1,n-1){
int u=read();
int v=read();
add(u,v);
}
prepare(1,-1);
dfs(1,-1,0);
rep(i,1,n){
if(i==n) println(ans[i]);
else printbk(ans[i]);
}
}
return 0;
}

Codeforces - 600E 树上启发式合并的更多相关文章

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

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

  2. Codeforces 208E - Blood Cousins(树上启发式合并)

    208E - Blood Cousins 题意 给出一棵家谱树,定义从 u 点向上走 k 步到达的节点为 u 的 k-ancestor.多次查询,给出 u k,问有多少个与 u 具有相同 k-ance ...

  3. 树上启发式合并(dsu on tree)学习笔记

    有丶难,学到自闭 参考的文章: zcysky:[学习笔记]dsu on tree Arpa:[Tutorial] Sack (dsu on tree) 先康一康模板题吧:CF 600E($Lomsat ...

  4. 神奇的树上启发式合并 (dsu on tree)

    参考资料 https://www.cnblogs.com/zhoushuyu/p/9069164.html https://www.cnblogs.com/candy99/p/dsuontree.ht ...

  5. CF EDU - E. Lomsat gelral 树上启发式合并

    学习:http://codeforces.com/blog/entry/44351 E. Lomsat gelral 题意: 给定一个以1为根节点的树,每个节点都有一个颜色,问每个节点的子树中,颜色最 ...

  6. dsu on tree (树上启发式合并) 详解

    一直都没出过算法详解,昨天心血来潮想写一篇,于是 dsu on tree 它来了 1.前置技能 1.链式前向星(vector 建图) 2.dfs 建树 3.剖分轻重链,轻重儿子 重儿子 一个结点的所有 ...

  7. dsu on tree 树上启发式合并 学习笔记

    近几天跟着dreagonm大佬学习了\(dsu\ on\ tree\),来总结一下: \(dsu\ on\ tree\),也就是树上启发式合并,是用来处理一类离线的树上询问问题(比如子树内的颜色种数) ...

  8. hdu6191(树上启发式合并)

    hdu6191 题意 给你一棵带点权的树,每次查询 \(u\) 和 \(x\) ,求以 \(u\) 为根结点的子树上的结点与 \(x\) 异或后最大的结果. 分析 看到子树,直接上树上启发式合并,看到 ...

  9. csu1811(树上启发式合并)

    csu1811 题意 给定一棵树,每个节点有颜色,每次仅删掉第 \(i\) 条边 \((a_i, b_i)\) ,得到两颗树,问两颗树节点的颜色集合的交集. 分析 转化一下,即所求答案为每次删掉 \( ...

随机推荐

  1. 解决0RA-04031故障

    1.客户反应报表数据很慢,简单查询5分钟都出不来. 2.登陆数据库服务器检查日志:Thu Mar 21 16:20:30 2013Errors in file /opt/oracle/diag/rdb ...

  2. IP协议、ARP协议等之温故知新

    今天才知道: 1.IP协议的固定部分长度为20字节.(貌似有一家运维工程师面试我的时候,问过我这个问题呢.) 2.IP数据包首部中的协议?? 答:协议:占8位,指出此数据报携带的数据使用何种协议以便目 ...

  3. 24、Linux 多线程压缩工具pigz 的学习

    转载: https://blog.csdn.net/q871761987/article/details/72230355 https://blog.csdn.net/woodcorpse/artic ...

  4. Recyclerview添加头布局和尾布局,点击效果

    简介: 本篇博客主要包括recyclerview添加多种布局以及添加头布局和尾布局,还有item点击事件 思路: 主要重写Recyclerview.Adapter中的一些方法 1.public int ...

  5. HackNine 避免在EditText中验证日期

    1.概要:    为什么不直接为EditTText设置一个点击监听器,而非要使用Button呢?     答案是:使用Button更安全,因为用户无法修改Button的文本内容.如果使用EditTex ...

  6. 关于eWebEditorAPI

    1.获取HTML document.getElementById(Iframe的名称).contentWindow.getHTML();在线API http://www.ewebeditor.net/ ...

  7. sql server重建系统数据库

    方法一:https://bbs.csdn.net/topics/100013082 方法二:http://blog.51cto.com/jimshu/1095780 *** 方法三:https://b ...

  8. CentOS 网络操作

    ifconfig:查看网卡信息 网卡配置文件位置: /etc/sysconfig/network-scripts/文件夹 nmtui:配置网卡 netstat -tlunp:查看端口信息 端口信息存储 ...

  9. 使用web3部署一个比较复杂的智能合约

    以太坊系列之二十一 使用web3部署比较复杂的智能合约 搭建私链上的雷电网络 以太坊系列之二十一 使用web3部署比较复杂的智能合约 1 雷电网络智能合约简单介绍 2 remix 无法部署使用了lib ...

  10. [转载] java中关于OOM的场景及解决方法

    1.OOM for Heap=>例如:java.lang.OutOfMemoryError: Java heapspace[分析] 此OOM是由于JVM中heap的最大值不满足需要,将设置hea ...