题目链接

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)的更多相关文章

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

    题目链接:http://codeforces.com/problemset/problem/600/E n个点的有根树,以1为根,每个点有一种颜色.我们称一种颜色占领了一个子树当且仅当没有其他颜色在这 ...

  2. CF 600E. Lomsat gelral(dsu on tree)

    解题思路 \(dsu\) \(on\) \(tree\)的模板题.暴力而优雅的算法,轻儿子的信息暴力清空,重儿子的信息保留,时间复杂度\(O(nlogn)\) 代码 #include<iostr ...

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

    600E - Lomsat gelral 题意 给出一颗以 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 「$Dsu \ on \ tree$模板」

    With $Dsu \ on \ tree$ we can answer queries of this type: How many vertices in the subtree of verte ...

  6. 【CodeForces】600 E. Lomsat gelral (dsu on tree)

    [题目]E. Lomsat gelral [题意]给定n个点的树,1为根,每个点有一种颜色ci,一种颜色占领一棵子树当且仅当子树内没有颜色的出现次数超过它,求n个答案——每棵子树的占领颜色的编号和Σc ...

  7. codeforces 600E Lomsat gelral

    题面:codeforces600E 学习一下$dsu \ on \ tree$.. 这个东西可以处理很多无修改子树问题,复杂度通常为$O(nlogn)$. 主要操作是:我们先把整棵树链剖一下,然后每次 ...

  8. cf600E. Lomsat gelral(dsu on tree)

    题意 题目链接 给出一个树,求出每个节点的子树中出现次数最多的颜色的编号和 Sol dsu on tree的裸题. 一会儿好好总结总结qwq #include<bits/stdc++.h> ...

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

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

随机推荐

  1. groovy与java中的多方法

    最近在学习groovy的时候从书里看到这么一个有趣的例子,刚开始我也猜错了: 最后测试答案是: son ----show 刚开始没理解,以为是num---show,但是后来看书上说是: test01接 ...

  2. 【vim】查找重复的连续的单词

    当你很快地打字时,很有可能会连续输入同一个单词两次,就像 this this.这种错误可能骗过任何一个人,即使是你自己重新阅读一遍也不可避免.幸运的是,有一个简单的正则表达式可以用来预防这个错误.使用 ...

  3. linux统计某个特定文件名的大小总和【原创】

    [hch@EAISRVBJ2 log]$find ./ -name "test_chs_00*"|xargs du -ck|grep total|awk 'BEGIN{sum=0} ...

  4. bootstrap 的媒体查询

    有时候需要对bootstap的样式自定义,比如说某个元素的“height”值,要放在与bootstrap媒体查询同步的样式里,才会兼容响应式布局. .container类是bootstrap的官方参考 ...

  5. 转载:Nginx是什么(1.1)《深入理解Nginx》(陶辉)

    原文:https://book.2cto.com/201304/19609.html 人们在了解新事物时,往往习惯通过类比来帮助自己理解事物的概貌.那么,我们在学习Nginx时也采用同样的方式,先来看 ...

  6. Go语言规格说明书 之 Go语句(Go statements)

    go version go1.11 windows/amd64 本文为阅读Go语言中文官网的规则说明书(https://golang.google.cn/ref/spec)而做的笔记,介绍Go语言的 ...

  7. Android 的网络编程

    android的网络编程分为2种:基于socket的,和基于http协议的. 基于socket的用法 服务器端: 先启动一个服务器端的socket     ServerSocket svr = new ...

  8. 并发之AQS原理(三) 如何保证并发

    并发之AQS原理(三) 如何保证并发 1. 如何保证并发 AbstractQueuedSynchronizer 维护了一个state(代表了共享资源)和一个FIFO线程等待队列(多线程竞争资源被阻塞时 ...

  9. hdu3183 rmq求区间最值的下标

    两个月前做的题,以后可以看看,是rmq关于求区间最值的下标 /* hdu3183 终点 给一个整数,可以删除m位,留下的数字形成一个新的整数 rmq 取n-m个数,使形成的数最小 */ #includ ...

  10. 使用Struts,实现简单的登录

    一.新建项目Struts 1.右键 new————Web Project 2.点击项目——右键——myeclipse——add Struts Capabilities.....——选择struts2. ...