题目描述

You are given a rooted tree with root in vertex 11 . Each vertex is coloured in some colour.

Let's call colour cc dominating in the subtree of vertex vv if there are no other colours that appear in the subtree of vertex vv more times than colour cc . So it's possible that two or more colours will be dominating in the subtree of some vertex.

The subtree of vertex vv is the vertex vv and all other vertices that contains vertex vv in each path to the root.

For each vertex vv find the sum of all dominating colours in the subtree of vertex vv .

题目分析

首先分析问题,发现求得是以当前节点为子树的众数和

考虑dsu,在更新答案时,我们统计每一个数的出现次数,如果大了就更新sum,否则更新次数

具体的dsu,我们可以采取重链剖分的思路

重儿子的大小最大,所以将每一个节点先赋为重儿子,在一次统计轻儿子,最后清空影响

在操作轻儿子时,可以用dfn来遍历

对于时间复杂度,因为\(wson_size>=n/2\) 所以,每一次只会操作\(n/2\),递归后,时间为\(O(n*log2(n))\)

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN=1e5+5;
int n,q,root;
int a[MAXN];
int lsh[MAXN];
vector<int>g[MAXN];
int x,y;
int sum;
int maxi;
int son[MAXN];
int size[MAXN];
int num[MAXN];
int dfn[MAXN];
int dfnc[MAXN];
int cnt=0;
void dfs1(int x,int fa)
{
dfn[x]=++cnt;
dfnc[cnt]=x;
size[x]=1;
int maxi=0;
for(int i=0;i<g[x].size();i++)
{
int v=g[x][i];
if(v==fa)
{
continue;
}
dfs1(v,x);
size[x]+=size[v];
if(maxi<size[v])
{
son[x]=v;
maxi=size[v];
}
}
}
int rec[MAXN];
void dfs(int x,int f,int check)
{
for(int i=0;i<g[x].size();i++)
{
int v=g[x][i];
if(v==f||v==son[x])
{
continue;
}
dfs(v,x,0);
} if(son[x])
{
dfs(son[x],x,1);
}
num[a[x]]++;
if(maxi<num[a[x]])
{
maxi=num[a[x]];
sum=a[x];
}
else if(maxi==num[a[x]])
{
sum+=a[x];
}
for(int i=0;i<g[x].size();i++)
{
int v=g[x][i];
if(v==f||v==son[x])
{
continue;
}
for(int j=dfn[v];j<=dfn[v]+size[v]-1;j++)
{
int key=dfnc[j];
num[a[key]]++;
if(maxi<num[a[key]])
{
maxi=num[a[key]];
sum=a[key];
}
else if(maxi==num[a[key]])
{
sum+=a[key];
}
}
}
rec[x]=sum;
// printf("%d %d\n",x,sum);
if(!check)
{
for(int j=dfn[x];j<=dfn[x]+size[x]-1;j++)
{
int key=dfnc[j];
num[a[key]]--;
}
maxi=0;
sum=0;
}
}
signed main()
{
scanf("%lld",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
for(int i=1;i<n;i++)
{
scanf("%lld %lld",&x,&y);
g[x].push_back(y);
g[y].push_back(x);
}
dfs1(1,0);
dfs(1,0,0);
for(int i=1;i<=n;i++)
{
printf("%lld ",rec[i]);
}
}

Lomsat gelral的更多相关文章

  1. Educational Codeforces Round 2 E. Lomsat gelral 启发式合并map

    E. Lomsat gelral Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/600/prob ...

  2. Codeforces 600 E - Lomsat gelral

    E - Lomsat gelral 思路1: 树上启发式合并 代码: #include<bits/stdc++.h> using namespace std; #define fi fir ...

  3. 【CF600E】 Lomsat gelral

    CF600E Lomsat gelral Solution 考虑一下子树的问题,我们可以把一棵树的dfn序搞出来,那么子树就是序列上的一段连续的区间. 然后就可以莫队飞速求解了. 但是这题还有\(\T ...

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

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

  5. 【CF600E】Lomsat gelral(dsu on tree)

    [CF600E]Lomsat gelral(dsu on tree) 题面 洛谷 CF题面自己去找找吧. 题解 \(dsu\ on\ tree\)板子题 其实就是做子树询问的一个较快的方法. 对于子树 ...

  6. CF 600 E. Lomsat gelral

    E. Lomsat gelral http://codeforces.com/contest/600/problem/E 题意: 求每个子树内出现次数最多的颜色(如果最多的颜色出现次数相同,将颜色编号 ...

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

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

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

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

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

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

  10. CF600E Lomsat gelral 和 CF741D Dokhtar-kosh paths

    Lomsat gelral 一棵以\(1\)为根的树有\(n\)个结点,每个结点都有一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号(若有数量一样的,则求编号和). \(n \le 10^ ...

随机推荐

  1. Dubbo多注册中心

    一.创建提供者08-provider-registers (1) 创建工程 直接复制05-provider-group工程,并命名为08-provider-registers (2) 修改配置文件 二 ...

  2. web管理的Powerdns

    在powerdns服务器上安装相应的包(基于epel源) [root@powerdns ~]# yum install pdns pdns-backend-mysql -y 在master-maira ...

  3. shell awk命令字符串拼接

    本节内容:awk命令实现字符串的拼接 输入文件的内容: TMALL_INVENTORY_30_GROUP my163149.cm6 3506 5683506 mysql-bin.000013 3273 ...

  4. centos 7 zookeeper 单体和集群搭建

    1.操作相关命令 1.0  安装命令     wget  :下载解压包 tar -xzvf  :解压 1.1  创建节点 create  / node : 创建一个名字为node的 空节点 creat ...

  5. Spring Boot对静态资源的映射规则

    规则一:所有 " /webjars/** " 请求都去classpath:/META-INF/resources/webjars/找资源 webjars:以jar包的方式引入静态资 ...

  6. 【C/C++】BanGDream活动点数计算器

    作为一个白嫖咸鱼,我每个活动都只打出三星卡就不玩了,于是写了一个模拟器,算算还要打几把hhh #include <iostream> #include <algorithm> ...

  7. 【C#】【假条生成系统】【单位剖析】如何判断在文本框输入了几个人名?

    我们规定,人名和人名之间使用顿号隔开 那么, 1个人,就是0个顿号 2个人,就是1个顿号 3个人,就是2个顿号 -- 所以我们可以判断文本框中顿号的出现次数. 出现0次,则为1人,出1次,则为两人. ...

  8. 关于Mysql java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)的问题

    问题所在: 1.连接数据库一个是密码是否正确, 2.driver是否对, 3.有么有jar包冲突,

  9. c++和c中const的区别

    const在c与c++的区别与使用 大学期间对c和c++的了解太少了,现在工作了导致自己来恶补,简单的const关键字里面的学问还是挺大的,越是基础的知识越是容易忘却,所以今天开始记录着自己每一天的学 ...

  10. 记一次 .NET 某市附属医院 Web程序 偶发性CPU爆高分析

    一:背景 1. 讲故事 这个月初,一位朋友加微信求助他的程序出现了 CPU 偶发性爆高,希望能有偿解决一下. 从描述看,这个问题应该困扰了很久,还是医院的朋友给力,开门就是 100块 红包 ,那既然是 ...