Codeforces - 600E 树上启发式合并
题意:求每一个子树存在最多颜色的颜色代号和(可重复)
本题是离线统计操作,因此可以直接合并重儿子已达到\(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 树上启发式合并的更多相关文章
- Codeforces 600E - Lomsat gelral(树上启发式合并)
600E - Lomsat gelral 题意 给出一颗以 1 为根的树,每个点有颜色,如果某个子树上某个颜色出现的次数最多,则认为它在这课子树有支配地位,一颗子树上,可能有多个有支配的地位的颜色,对 ...
- Codeforces 208E - Blood Cousins(树上启发式合并)
208E - Blood Cousins 题意 给出一棵家谱树,定义从 u 点向上走 k 步到达的节点为 u 的 k-ancestor.多次查询,给出 u k,问有多少个与 u 具有相同 k-ance ...
- 树上启发式合并(dsu on tree)学习笔记
有丶难,学到自闭 参考的文章: zcysky:[学习笔记]dsu on tree Arpa:[Tutorial] Sack (dsu on tree) 先康一康模板题吧:CF 600E($Lomsat ...
- 神奇的树上启发式合并 (dsu on tree)
参考资料 https://www.cnblogs.com/zhoushuyu/p/9069164.html https://www.cnblogs.com/candy99/p/dsuontree.ht ...
- CF EDU - E. Lomsat gelral 树上启发式合并
学习:http://codeforces.com/blog/entry/44351 E. Lomsat gelral 题意: 给定一个以1为根节点的树,每个节点都有一个颜色,问每个节点的子树中,颜色最 ...
- dsu on tree (树上启发式合并) 详解
一直都没出过算法详解,昨天心血来潮想写一篇,于是 dsu on tree 它来了 1.前置技能 1.链式前向星(vector 建图) 2.dfs 建树 3.剖分轻重链,轻重儿子 重儿子 一个结点的所有 ...
- dsu on tree 树上启发式合并 学习笔记
近几天跟着dreagonm大佬学习了\(dsu\ on\ tree\),来总结一下: \(dsu\ on\ tree\),也就是树上启发式合并,是用来处理一类离线的树上询问问题(比如子树内的颜色种数) ...
- hdu6191(树上启发式合并)
hdu6191 题意 给你一棵带点权的树,每次查询 \(u\) 和 \(x\) ,求以 \(u\) 为根结点的子树上的结点与 \(x\) 异或后最大的结果. 分析 看到子树,直接上树上启发式合并,看到 ...
- csu1811(树上启发式合并)
csu1811 题意 给定一棵树,每个节点有颜色,每次仅删掉第 \(i\) 条边 \((a_i, b_i)\) ,得到两颗树,问两颗树节点的颜色集合的交集. 分析 转化一下,即所求答案为每次删掉 \( ...
随机推荐
- SQL Server 2008 R2 Express 不能启动
今天,新安装了Sql Server 2008 R2 Express,准备部署相应系统,在完成了数据库还原,系统部署以后,从浏览器里输入系统网址,出现登录页面,登录时报错,无法连上数据库.在查找原因的过 ...
- 6.AND & OR 运算符
AND 和 OR 运算符用于基于一个以上的条件对记录进行过滤 AND 和 OR 运算符 AND 和 OR 可在 WHERE 子语句中把两个或多个条件结合起来. 如果第一个条件和第二个条件都成立,则 A ...
- C#使用var定义变量时的四个特点
使用var定义变量时有以下四个特点: 1. 必须在定义时初始化.也就是必须是var s = “abcd”形式: 2. 一但初始化完成,就不能再给变量赋与初始化值类型不同的值了. 3. var要求是 ...
- Python基础入门-数据类型
一.变量 1)变量定义 在python中,我们可以把变量理解为一个值,变量是一个标签名,变量是有对应的一个值. name = 100(name是变量名 = 号是赋值号100是变量的值) 2)变量赋值 ...
- dynamic和nullable一起使用时的注意
dynamic和nullable一起使用时的注意
- 以太坊系列之十四: solidity特殊函数
solidity中的特殊函数 括号里面有类型和名字的是参数,只有类型是返回值. block.blockhash(uint blockNumber) returns (bytes32): hash of ...
- 数据库处理session类
<?php /* * 使用数据库处理session * php.ini 中 session.save_handler 设为 "user" */ class Dbsession ...
- CentOS 6.9下PXE+Kickstart无人值守安装操作系统
一.简介 1.1 什么是PXE PXE(Pre-boot Execution Environment,预启动执行环境)是由Intel公司开发的最新技术,工作于Client/Server的网络模式,支持 ...
- 20165219 2017-2018-2 《Java程序设计》第7周学习总结
20165219 2017-2018-2 <Java程序设计>第7周学习总结 课本知识总结 第11章 JDBC与MySQL数据库 连接数据库 1下载JDBC-MySQL数据库驱动 2 加载 ...
- YARN 的调度选项
YARN 中有三种调度器: 1. FIFO 调度器 (FIFO Scheduler) 应用在一个队列中,按照提交的顺序运行应用. 缺点:小作业如果在大作业后面提交,将会一直等到大作业结束才运行. 2. ...