Codeforces.600E.Lomsat gelral(dsu on tree)
\(Description\)
给定一棵树。求以每个点为根的子树中,出现次数最多的颜色的和。
\(Solution\)
dsu on tree模板题.
用\(sum[i]\)表示出现次数为\(i\)的颜色的和,\(cnt[i]\)表示出现次数为\(i\)的颜色有多少个(其实用个\(Max\)表示当前最多的次数,和每种颜色出现次数\(tm[i]\)就好了),然后。。就这样了。。
可以用DFS序代替DFS减少一些常数。
再写一遍dsu on tree大体过程:(设当前点为\(x\))
计算轻儿子子树的答案,并删掉轻儿子的贡献(大多数时候);
计算重儿子子树的答案,保留重儿子的贡献(有时候不需要?);
加入\(x\)轻儿子子树的贡献;
得到\(x\)的答案;
如果\(x\)不是重儿子,则删掉它整个子树的贡献(本题直接将\(Max,Sum\)清0就好了)。
复杂度证明:每个点会在它上面的每条轻边处暴力统计一次。而每个点到根节点的路径上只有\(O(\log n)\)条轻边。
优化:(DFS序)
//62ms 13400KB
#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 300000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=1e5+5;
int skip,Enum,H[N],nxt[N<<1],to[N<<1],Max,col[N],sz[N],son[N],tm[N],A[N],L[N],R[N];
LL Sum,Ans[N];
char IN[MAXIN],*SS=IN,*TT=IN;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline void AE(int u,int v)
{
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
}
void DFS1(int x,int fa)
{
static int Index=0;
A[L[x]=++Index]=x;
int mx=0; sz[x]=1;
for(int i=H[x],v; i; i=nxt[i])
if((v=to[i])!=fa)
{
DFS1(v,x), sz[x]+=sz[v];
if(sz[v]>mx) mx=sz[v], son[x]=v;
}
R[x]=Index;
}
inline void Add(int c)
{
if(++tm[c]>Max) Max=tm[c], Sum=c;
else if(tm[c]==Max) Sum+=c;
}
void Solve(int x,int fa,int keep)
{
for(int i=H[x]; i; i=nxt[i])
if(to[i]!=fa && to[i]!=son[x]) Solve(to[i],x,0);
if(son[x]) Solve(son[x],x,1);
Add(col[x]);
for(int i=H[x],v; i; i=nxt[i])
if((v=to[i])!=fa && v!=son[x])
for(int j=L[v]; j<=R[v]; ++j) Add(col[A[j]]);
Ans[x]=Sum;
if(!keep)
{
Max=Sum=0;
for(int i=L[x]; i<=R[x]; ++i) --tm[col[A[i]]];
}
}
int main()
{
int n=read();
for(int i=1; i<=n; ++i) col[i]=read();
for(int i=1; i<n; ++i) AE(read(),read());
DFS1(1,1), Solve(1,1,1);
for(int i=1; i<=n; ++i) printf("%I64d ",Ans[i]);
return 0;
}
未优化:
//93ms 9100KB
#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 300000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=1e5+5;
int skip,Enum,H[N],nxt[N<<1],to[N<<1],Max,col[N],sz[N],son[N],tm[N];
LL Sum,Ans[N];
char IN[MAXIN],*SS=IN,*TT=IN;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline void AE(int u,int v)
{
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
}
void DFS1(int x,int fa)
{
int mx=0; sz[x]=1;
for(int i=H[x],v; i; i=nxt[i])
if((v=to[i])!=fa)
{
DFS1(v,x), sz[x]+=sz[v];
if(sz[v]>mx) mx=sz[v], son[x]=v;
}
}
void Add(int x,int fa)
{
if(++tm[col[x]]>Max) Max=tm[col[x]], Sum=col[x];
else if(tm[col[x]]==Max) Sum+=col[x];
for(int i=H[x]; i; i=nxt[i])
if(to[i]!=fa && to[i]!=skip) Add(to[i],x);
}
void Del(int x,int fa)
{
--tm[col[x]];
for(int i=H[x]; i; i=nxt[i])
if(to[i]!=fa) Del(to[i],x);
}
void Solve(int x,int fa,int keep)
{
for(int i=H[x]; i; i=nxt[i])
if(to[i]!=fa && to[i]!=son[x]) Solve(to[i],x,0);
if(son[x]) Solve(son[x],x,1), skip=son[x];
Add(x,fa), Ans[x]=Sum, skip=0;
if(!keep) Max=Sum=0, Del(x,fa);
}
int main()
{
int n=read();
for(int i=1; i<=n; ++i) col[i]=read();
for(int i=1; i<n; ++i) AE(read(),read());
DFS1(1,1), Solve(1,1,1);
for(int i=1; i<=n; ++i) printf("%I64d ",Ans[i]);
return 0;
}
Codeforces.600E.Lomsat gelral(dsu on tree)的更多相关文章
- Codeforces 600E. Lomsat gelral(Dsu on tree学习)
题目链接:http://codeforces.com/problemset/problem/600/E n个点的有根树,以1为根,每个点有一种颜色.我们称一种颜色占领了一个子树当且仅当没有其他颜色在这 ...
- CF 600E. Lomsat gelral(dsu on tree)
解题思路 \(dsu\) \(on\) \(tree\)的模板题.暴力而优雅的算法,轻儿子的信息暴力清空,重儿子的信息保留,时间复杂度\(O(nlogn)\) 代码 #include<iostr ...
- Codeforces 600E - Lomsat gelral(树上启发式合并)
600E - Lomsat gelral 题意 给出一颗以 1 为根的树,每个点有颜色,如果某个子树上某个颜色出现的次数最多,则认为它在这课子树有支配地位,一颗子树上,可能有多个有支配的地位的颜色,对 ...
- Codeforces 600E Lomsat gelral(dsu on tree)
dsu on tree板子题.这个trick保证均摊O(nlogn)的复杂度,要求资瓷O(1)将一个元素插入集合,清空集合时每个元素O(1)删除.(当然log的话就变成log^2了) 具体的,每次先遍 ...
- 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 ...
- 【CodeForces】600 E. Lomsat gelral (dsu on tree)
[题目]E. Lomsat gelral [题意]给定n个点的树,1为根,每个点有一种颜色ci,一种颜色占领一棵子树当且仅当子树内没有颜色的出现次数超过它,求n个答案——每棵子树的占领颜色的编号和Σc ...
- codeforces 600E Lomsat gelral
题面:codeforces600E 学习一下$dsu \ on \ tree$.. 这个东西可以处理很多无修改子树问题,复杂度通常为$O(nlogn)$. 主要操作是:我们先把整棵树链剖一下,然后每次 ...
- cf600E. Lomsat gelral(dsu on tree)
题意 题目链接 给出一个树,求出每个节点的子树中出现次数最多的颜色的编号和 Sol dsu on tree的裸题. 一会儿好好总结总结qwq #include<bits/stdc++.h> ...
- Codeforces 600E Lomsat gelral (树上启发式合并)
题目链接 Lomsat gelral 占坑……等深入理解了再来补题解…… #include <bits/stdc++.h> using namespace std; #define rep ...
随机推荐
- np.savetxt()——将array保存到txt文件,并保持原格式
问题:1.如何将array保存到txt文件中?2.如何将存到txt文件中的数据读出为ndarray类型? 需求:科学计算中,往往需要将运算结果(array类型)保存到本地,以便进行后续的数据分析. 解 ...
- UML和模式应用4:初始阶段(4)--需求制品之用例模型模板示例
1. 前言 UP开发包括四个阶段:初始阶段.细化阶段.构建阶段.移交阶段: UP每个阶段包括 业务建模.需求.设计等科目: 其中需求科目对应的需求制品包括:设想.业务规则.用例模型.补充性规格说明.词 ...
- 13-JS中的面向对象
创建对象的几种常用方式 1.使用Object或对象字面量创建对象 2.工厂模式创建对象 3.构造函数模式创建对象 4.原型模式创建对象 1.使用Object或对象字面量创建对象 JS中最基本创建对象的 ...
- PHP获取网卡的MAC地址原码;目前支持WIN/LINUX系统 获取机器网卡的物理(MAC)地址
声明转换于其它博客当中的. <?php /** 获取网卡的MAC地址原码:目前支持WIN/LINUX系统 获取机器网卡的物理(MAC)地址 **/ class GetMacAddr{ var $ ...
- jquery submit ie6下失效的原因分析及解决方法
ie6中, $('a.btn').click(function(){ form.submit(); }) 点击失效: 分析: 微软低版本浏览器会先执行link标签的自身事件也就是href事件,这样就中 ...
- vue首次赋值不触发watch
可通过其immediate 属性进行配置,默认为false watch:{ "aaa":{ immediate:true, handler:function(){ } }
- python 全栈开发,Day30(第一次面向对象考试)
月考题: python 全栈11期月考题 一 基础知识:(70分) 1.文件操作有哪些模式?请简述各模式的作用(2分) 2.详细说明tuple.list.dict的用法,以及它们的特点(3分) 3.解 ...
- 数据库中的null用法
- 2018-2019 2 20165203 《网络对抗技术》Exp5 MSF基础
2018-2019 2 20165203 <网络对抗技术>Exp5 MSF基础 实验内容 本实践目标是掌握metasploit的基本应用方式,重点常用的三种攻击方式的思路.具体需要完成: ...
- php安全篇过滤用户输入的参数(转)
规则 1:绝不要信任外部数据或输入 关于Web应用程序安全性,必须认识到的第一件事是不应该信任外部数据.外部数据(outside data) 包括不是由程序员在PHP代码中直接输入的任何数据.在采取措 ...