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 vertex $v$ has some property in $O (n \log n)$ time (for all of the queries)?
这题写的是轻重儿子(重链剖分)版本的 $Dsu \ on \ tree$
具体流程如下:
每次先递归计算轻儿子,再单独递归重儿子,计算完后轻儿子的一些信息需要删掉,但是重儿子的信息无需删除,如此出解,相当于是优化了暴力的多余部分
每个节点会作为轻儿子被计算,重链剖分上垂直有 $\log n$ 条链,故复杂度 $O (n \log n)$
代码
#include <iostream>
#include <cstdio>
#include <cstring> using namespace std; typedef long long LL; const int MAXN = 1e05 + ;
const int MAXM = 1e05 + ;
const int MAXC = 1e05 + ; struct LinkedForwardStar {
int to; int next;
} ; LinkedForwardStar Link[MAXM << ];
int Head[MAXN]= {};
int size = ; void Insert (int u, int v) {
Link[++ size].to = v;
Link[size].next = Head[u]; Head[u] = size;
} int N;
int colour[MAXN]; int son[MAXN]= {};
int subsize[MAXN]= {};
void DFS (int root, int father) {
son[root] = - ;
subsize[root] = ;
for (int i = Head[root]; i; i = Link[i].next) {
int v = Link[i].to;
if (v == father)
continue;
DFS (v, root);
subsize[root] += subsize[v];
if (son[root] == - || subsize[v] > subsize[son[root]])
son[root] = v;
}
}
int vis[MAXN]= {};
int total[MAXC]= {};
int maxv = ;
LL sum = ;
void calc (int root, int father, int delta) { // 统计答案
total[colour[root]] += delta;
if (delta > && total[colour[root]] >= maxv) {
if (total[colour[root]] > maxv)
sum = , maxv = total[colour[root]];
sum += colour[root];
}
for (int i = Head[root]; i; i = Link[i].next) {
int v = Link[i].to;
if (v == father || vis[v])
continue;
calc (v, root, delta);
}
}
LL answer[MAXN]= {};
void Solve (int root, int father, int type) { // type表示是不是重儿子信息
for (int i = Head[root]; i; i = Link[i].next) {
int v = Link[i].to;
if (v == father || v == son[root])
continue;
Solve (v, root, );
}
if (~ son[root])
Solve (son[root], root, ), vis[son[root]] = ;
calc (root, father, );
answer[root] = sum;
if (~ son[root])
vis[son[root]] = ;
if (! type) // 如果是轻儿子信息就需删除
calc (root, father, - ), maxv = sum = ;
} int getnum () {
int num = ;
char ch = getchar (); while (! isdigit (ch))
ch = getchar ();
while (isdigit (ch))
num = (num << ) + (num << ) + ch - '', ch = getchar (); return num;
} int main () {
N = getnum ();
for (int i = ; i <= N; i ++)
colour[i] = getnum ();
for (int i = ; i < N; i ++) {
int u = getnum (), v = getnum ();
Insert (u, v), Insert (v, u);
}
DFS (, ), Solve (, , );
for (int i = ; i <= N; i ++) {
if (i > )
putchar (' ');
printf ("%lld", answer[i]);
}
puts (""); return ;
} /*
4
1 2 3 4
1 2
2 3
2 4
*/ /*
15
1 2 3 1 2 3 3 1 1 3 2 2 1 2 3
1 2
1 3
1 4
1 14
1 15
2 5
2 6
2 7
3 8
3 9
3 10
4 11
4 12
4 13
*/
Codeforces 600E - Lomsat gelral 「$Dsu \ on \ tree$模板」的更多相关文章
- Codeforces 600E Lomsat gelral(dsu on tree)
dsu on tree板子题.这个trick保证均摊O(nlogn)的复杂度,要求资瓷O(1)将一个元素插入集合,清空集合时每个元素O(1)删除.(当然log的话就变成log^2了) 具体的,每次先遍 ...
- Codeforces 600E - Lomsat gelral(树上启发式合并)
600E - Lomsat gelral 题意 给出一颗以 1 为根的树,每个点有颜色,如果某个子树上某个颜色出现的次数最多,则认为它在这课子树有支配地位,一颗子树上,可能有多个有支配的地位的颜色,对 ...
- Codeforces.600E.Lomsat gelral(dsu on tree)
题目链接 dsu on tree详见这. \(Description\) 给定一棵树.求以每个点为根的子树中,出现次数最多的颜色的和. \(Solution\) dsu on tree模板题. 用\( ...
- Codeforces 600E Lomsat gelral (树上启发式合并)
题目链接 Lomsat gelral 占坑……等深入理解了再来补题解…… #include <bits/stdc++.h> using namespace std; #define rep ...
- Codeforces 600E. Lomsat gelral(Dsu on tree学习)
题目链接:http://codeforces.com/problemset/problem/600/E n个点的有根树,以1为根,每个点有一种颜色.我们称一种颜色占领了一个子树当且仅当没有其他颜色在这 ...
- codeforces 600E Lomsat gelral
题面:codeforces600E 学习一下$dsu \ on \ tree$.. 这个东西可以处理很多无修改子树问题,复杂度通常为$O(nlogn)$. 主要操作是:我们先把整棵树链剖一下,然后每次 ...
- codeforces 600E. Lomsat gelral 启发式合并
题目链接 给一颗树, 每个节点有初始的颜色值. 1为根节点.定义一个节点的值为, 它的子树中出现最多的颜色的值, 如果有多种颜色出现的次数相同, 那么值为所有颜色的值的和. 每一个叶子节点是一个map ...
- codeforces 600E . Lomsat gelral (线段树合并)
You are given a rooted tree with root in vertex 1. Each vertex is coloured in some colour. Let's cal ...
- 【Codeforces】600E. Lomsat gelral
Codeforces 600E. Lomsat gelral 学习了一下dsu on tree 所以为啥是dsu而不是dfs on tree??? 这道题先把这棵树轻重链剖分了,然后先处理轻儿子,处理 ...
随机推荐
- 云平台项目--学习经验--BootstrapValidate表单验证插件
使用前提,需要加载jquery和bootstrap库.并且引入bootstrapValidator.js和bootstrapValidator.css文件然后建立一个form表单,添加表单控件,表单控 ...
- WPF使用路径(URI)引用资源文件
Uri uri = new Uri("pack://application:,,,/程序集名称;component/Resources/bj.png", UriKind.Absol ...
- C#简述(一)
详情请参考:http://www.runoob.com/csharp/csharp-tutorial.html 1.C# 是一个简单的.现代的.通用的.面向对象的编程语言,它是由微软(Microsof ...
- TClientDataSet[9]: 计算字段和 State
TClientDataSet 中计算字段有两种: Calculated(计算字段).InternalCalc(内部计算字段). 两者区别是: Calculated 在每次需要时都要重新计算; Inte ...
- oracle无法通过IP地址进行连接
在oracle安装完成之后有时候后无法使用IP地址进行连接或者压根无法进行连接,此时我们可以通过配置oracle的监听来解决这个问题: 在开始菜单中找到oracle文件夹的net manager,如下 ...
- SSH协议详解
简介 SSH只是一个协议,基于这个协议有不同的实现,这些实现中有开源,也有收费. 原理 普通网络通信一般是明文通信,数据容易被中间人拦截并且解析,而SSH协议则提供了基于内容加密服务. 流程: 第一种 ...
- Cocos2d-x 3.2 打包Android平台APK
(转自:http://www.cnblogs.com/Richard-Core/p/3855130.html) 从cocos2dx 3.2项目打包成apk安卓应用文件,搭建安卓环境的步骤有点繁琐,但搭 ...
- ASP.Net执行cmd命令的实现代码
using System; using System.Collections; using System.Configuration; using System.Data; using System. ...
- 界面编程之QT的Socket通信20180730
/*******************************************************************************************/ 一.linu ...
- 《剑指offer》— JavaScript(29)最小的K个数
最小的K个数 题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4. 思路一 使用JavaScript的Array对象的so ...