题面:codeforces600E

学习一下$dsu \ on \ tree$。。

这个东西可以处理很多无修改子树问题,复杂度通常为$O(nlogn)$。

主要操作是:我们先把整棵树链剖一下,然后每次先递归轻儿子,再递归重儿子。

对于每棵子树,我们暴力加入整棵子树的贡献。如果是重儿子的子树则另外处理:加入贡献时不考虑加重儿子所在的子树,而在消除贡献时也不消除重儿子的子树,直到它成为某个点的轻儿子的子树的一部分时再消除贡献。

复杂度:因为每个轻儿子最多被加入$O(logn)$次(递归轻儿子时$size$至少$/2$),每条重链最多只会被加入$O(logn)$次,所以复杂度是$O(nlogn)$的。

说得有点玄学,还是看看代码吧。。

 //It is made by wfj_2048~
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define inf (1<<30)
#define N (200010)
#define il inline
#define RG register
#define ll long long using namespace std; struct edge{ int nt,to; }g[N<<]; int head[N],col[N],son[N],sz[N],c[N],n,num,Mx,flag;
ll ans[N],Sum; il int gi(){
RG int x=,q=; RG char ch=getchar();
while ((ch<'' || ch>'') && ch!='-') ch=getchar();
if (ch=='-') q=-,ch=getchar();
while (ch>='' && ch<='') x=x*+ch-,ch=getchar();
return q*x;
} il void insert(RG int from,RG int to){
g[++num]=(edge){head[from],to},head[from]=num; return;
} il void dfs1(RG int x,RG int p){
sz[x]=; RG int v;
for (RG int i=head[x];i;i=g[i].nt){
v=g[i].to; if (v==p) continue;
dfs1(v,x),sz[x]+=sz[v];
if (sz[son[x]]<=sz[v]) son[x]=v;
}
return;
} il void add(RG int x,RG int p,RG int val){
col[c[x]]+=val; RG int v;
if (Mx<col[c[x]]) Mx=col[c[x]],Sum=c[x];
else if (Mx==col[c[x]]) Sum+=c[x];
for (RG int i=head[x];i;i=g[i].nt){
v=g[i].to; if (v==p || v==flag) continue;
add(v,x,val);
}
return;
} il void dfs2(RG int x,RG int p,RG int fg){
RG int v;
for (RG int i=head[x];i;i=g[i].nt){
v=g[i].to; if (v!=p && v!=son[x]) dfs2(v,x,);
}
if (son[x]) dfs2(son[x],x,),flag=son[x];
add(x,p,),flag=,ans[x]=Sum;
if (fg) add(x,p,-),Mx=Sum=; return;
} int main(){
#ifndef ONLINE_JUDGE
freopen("600E.in","r",stdin);
freopen("600E.out","w",stdout);
#endif
n=gi();
for (RG int i=;i<=n;++i) c[i]=gi();
for (RG int i=,u,v;i<n;++i)
u=gi(),v=gi(),insert(u,v),insert(v,u);
dfs1(,),dfs2(,,);
for (RG int i=;i<=n;++i) printf("%I64d ",ans[i]);
return ;
}

codeforces 600E Lomsat gelral的更多相关文章

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

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

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

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

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

    题目链接:http://codeforces.com/problemset/problem/600/E n个点的有根树,以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 启发式合并

    题目链接 给一颗树, 每个节点有初始的颜色值. 1为根节点.定义一个节点的值为, 它的子树中出现最多的颜色的值, 如果有多种颜色出现的次数相同, 那么值为所有颜色的值的和. 每一个叶子节点是一个map ...

  6. 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 ...

  7. Codeforces.600E.Lomsat gelral(dsu on tree)

    题目链接 dsu on tree详见这. \(Description\) 给定一棵树.求以每个点为根的子树中,出现次数最多的颜色的和. \(Solution\) dsu on tree模板题. 用\( ...

  8. 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 ...

  9. 【Codeforces】600E. Lomsat gelral

    Codeforces 600E. Lomsat gelral 学习了一下dsu on tree 所以为啥是dsu而不是dfs on tree??? 这道题先把这棵树轻重链剖分了,然后先处理轻儿子,处理 ...

随机推荐

  1. Android文件/文件夹选择器(支持多选操作),已封装为lib库,直接添加依赖即可。

    话不多少,先上图一览: 接下来我们开始写个app测试: 1.新建Android工程:FileSelectorTest 2.更改MainActivity: 在里面写四个textview模拟button, ...

  2. RequireJS -Javascript模块化(一、简介)

    1.认识RequireJS RequireJs官网(http://requirejs.org/)的描述: RequireJS is a JavaScript file and module loade ...

  3. VBS 操作Excel

    VBS操作Excel 打开excel Dim objExcel,objWorkbook,objSheet Set objExcel=CreateObject("excel.applicati ...

  4. C++之构造函数、拷贝类型

    无参数的构造函数适合没初始化值的初始化对象,而引用拷贝适合创建对象时用另一个对象对其初始化,如果此时用的是浅拷贝则释放一个对象内存时系统会释放2次从而出错(因为它指向同一个内存),深拷贝就不存在这个问 ...

  5. loadrunner如何设置所有虚拟用户只运行一次脚本?

    1,设置所有虚拟用户只运行一次脚本 进入场景conroller,如下图设置.初始化和启动Vuser设置都可以,看具体要求,但持续时间一定要选择“完成前一直运行”,这样设置就可以让所有Vuser只运行一 ...

  6. PHP函数库(core)

    数组函数: array_change_key_case — 返回字符串键名全为小写或大写的数组 array_change_key_case() 将 input 数组中的所有键名改为全小写或大写.改变是 ...

  7. .NET面试题5

    常见面试题目: 1. const和readonly有什么区别? 2. 哪些类型可以定义为常量?常量const有什么风险? 3. 字段与属性有什么异同? 4. 静态成员和非静态成员的区别? 5. 自动属 ...

  8. C#中 计时器用法 运行时间

    有时候我们会需要计算某段代码运行的时间 比如一个sql查询,记录一段代码所花费的时间等等代码如下: System.Diagnostics.Stopwatch watch = new System.Di ...

  9. JavaFX--第3天窗口布局

    1.windows之间的交互 2.关闭程序 3.布局镶嵌 1.windows之间的交互 我们要实现“确定”.“取消”之类的功能:就像我们平时使用Word的时候要关闭会提示要不要保存的信息. 步骤如下: ...

  10. Win2D 官方文章系列翻译 - 像素格式

    本文为个人博客备份文章,原文地址: http://validvoid.net/win2d-pixel-formats/ DirectXPixelFormat 枚举 包含了 Direct3D 和 DXG ...