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

本题是离线统计操作,因此可以直接合并重儿子已达到\(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. bzoj5392 [Lydsy1806月赛]路径统计

    传送门 分析 我们设sum[x]为小于等于x的点现在有多少联通 于是一个序列合法当且只当sum[R]-sum[L-1]=len且所有点度数不大于2 我们知道如果对于序列[L,R]满足条件则[L+1,R ...

  2. linux蓝屏时间修改

    setterm -blank 2   #/etc/profile里添加这样一句话,可以让屏幕2分钟后没有信号(蓝屏) setterm -blank 0   #/etc/profile里添加这样一句话, ...

  3. Entity Framework 6.0 Tutorials(2):Async query and Save

    Async query and Save: You can take advantage of asynchronous execution of .Net 4.5 with Entity Frame ...

  4. 在Global.asax文件的Application_BeginRequest中获取request请求内容

    protected void Application_BeginRequest(object sender, EventArgs e) { try { string isLogRequest = Sy ...

  5. Jmeter接口测试-基于nodejs的to do list项目说明

    一.了解测试项目 我们的测试项目叫做smile_task,简称sm_task.这是一个基于nodejs超简单的todo list. 它的主要流程就是:输入标题描述---点击创建一个任务---编辑修改任 ...

  6. 编写高质量代码改善C#程序的157个建议——建议35:使用default为泛型类型变量指定初始值

    建议35:使用default为泛型类型变量指定初始值 有些算法,比如泛型集合List<T>的Find算法,所查找的对象可能会是值类型,也有可能是引用类型.在这种算法内部,我们常常会为这些值 ...

  7. 献上一款漂亮的手写PHP验证码

    献上一款漂亮的PHP验证码,可以根据个人需求作调整,代码如下(审美观不同,欢迎吐槽): <?php /** * Author: xiongwei * Email: 695704253@qq.co ...

  8. ColorMatrixFilter色彩矩阵滤镜;

    包 flash.filters 类 public final class ColorMatrixFilter 继承 ColorMatrixFilter  BitmapFilter  Object 使用 ...

  9. POJ - 1328 Radar Installation(贪心区间选点+小学平面几何)

    Input The input consists of several test cases. The first line of each case contains two integers n ...

  10. wp8扩展器大全

    <Extensions> <!--扩展照片中心--> <Extension ExtensionName="Photos_Extra_Hub" Cons ...