600E - Lomsat gelral

题意

给出一颗以 1 为根的树,每个点有颜色,如果某个子树上某个颜色出现的次数最多,则认为它在这课子树有支配地位,一颗子树上,可能有多个有支配的地位的颜色,对每颗子树分别求有支配地位的颜色的和(把颜色这个权值相加)。

分析

树上启发式合并模板题。

参考blog1

参考blog2

复杂度证明

如果暴力去搜索,显然是 \(O(n^2)\) 的算法,可以考虑优化,当我们搜索到节点 u 时,最后去搜索 u 的子节点中子树节点数量最大的子节点(树链剖分求出重儿子),并保留这个子节点所在子树的状态(颜色数量信息),这样在更新贡献的时候可以直接跳过它了。复杂度 \(O(nlogn)\)。

code

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int MAXN = 2e5 + 10;
  5. int n;
  6. int fa[MAXN], son[MAXN], dep[MAXN], siz[MAXN];
  7. int col[MAXN];
  8. int cnt, head[MAXN];
  9. struct Edge {
  10. int to, next;
  11. }e[MAXN];
  12. void addedge(int u, int v) {
  13. e[cnt].to = v;
  14. e[cnt].next = head[u];
  15. head[u] = cnt++;
  16. }
  17. void dfs(int u) {
  18. siz[u] = 1; son[u] = 0;
  19. for(int i = head[u]; ~i; i = e[i].next) {
  20. if(e[i].to != fa[u]) {
  21. fa[e[i].to] = u;
  22. dep[e[i].to] = dep[u] + 1;
  23. dfs(e[i].to);
  24. if(siz[e[i].to] > siz[son[u]]) son[u] = e[i].to;
  25. siz[u] += siz[e[i].to];
  26. }
  27. }
  28. }
  29. int vis[MAXN];
  30. ll sum, mx, C[MAXN];
  31. ll ans[MAXN];
  32. void update(int u, int c) {
  33. C[col[u]] += c;
  34. if(c > 0 && C[col[u]] >= mx) {
  35. if(C[col[u]] > mx) { sum = 0; mx = C[col[u]]; }
  36. sum += col[u];
  37. }
  38. for(int i = head[u]; ~i; i = e[i].next) {
  39. if(e[i].to != fa[u] && !vis[e[i].to]) update(e[i].to, c);
  40. }
  41. }
  42. void dfs1(int u, int flg) {
  43. for(int i = head[u]; ~i; i = e[i].next) {
  44. if(e[i].to != fa[u] && e[i].to != son[u]) dfs1(e[i].to, 1);
  45. }
  46. if(son[u]) {
  47. dfs1(son[u], 0);
  48. vis[son[u]] = 1;
  49. }
  50. update(u, 1); ans[u] = sum;
  51. if(son[u]) vis[son[u]] = 0;
  52. if(flg) {
  53. update(u, -1);
  54. sum = 0; mx = 0;
  55. }
  56. }
  57. int main() {
  58. memset(head, -1, sizeof head);
  59. scanf("%d", &n);
  60. for(int i = 1; i <= n; i++) {
  61. scanf("%d", &col[i]);
  62. }
  63. for(int i = 1; i < n; i++) {
  64. int x, y;
  65. scanf("%d%d", &x, &y);
  66. addedge(x, y);
  67. addedge(y, x);
  68. }
  69. dfs(1);
  70. dfs1(1, -1);
  71. for(int i = 1; i <= n; i++) {
  72. printf("%I64d%c", ans[i], i == n ? '\n' : ' ');
  73. }
  74. return 0;
  75. }

Codeforces 600E - Lomsat gelral(树上启发式合并)的更多相关文章

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

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

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

  3. CF 600 E Lomsat gelral —— 树上启发式合并

    题目:http://codeforces.com/contest/600/problem/E 看博客:https://blog.csdn.net/blue_kid/article/details/82 ...

  4. CF600E Lomsat gelral 树上启发式合并

    题目描述 有一棵 \(n\) 个结点的以 \(1\) 号结点为根的有根树. 每个结点都有一个颜色,颜色是以编号表示的, \(i\) 号结点的颜色编号为 \(c_i\)​. 如果一种颜色在以 \(x\) ...

  5. 【CF600E】Lomsat gelral——树上启发式合并

    (题面来自luogu) 题意翻译 一棵树有n个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. ci <= n <= 1e5 裸题.统计时先扫一遍得到出 ...

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

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

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

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

  8. codeforces 600E. Lomsat gelral 启发式合并

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

  9. Codeforces 600 E. Lomsat gelral (dfs启发式合并map)

    题目链接:http://codeforces.com/contest/600/problem/E 给你一棵树,告诉你每个节点的颜色,问你以每个节点为根的子树中出现颜色次数最多的颜色编号和是多少. 最容 ...

随机推荐

  1. oracle 隔离级别、事务怎么开始的以及如何查看数据库采用字符集

    把一下语句全部粘贴至控制台运行后可以查看oracle 隔离级别 declare trans_id ); begin trans_id := dbms_transaction.local_transac ...

  2. bayes学习笔记

    贝叶斯(BAYES)判别思想是根据先验概率求出后验概率,并依据后验概率分布作出统计推断.所谓先验概率,就是用概率来描述人们事先对所研究的对象的认识的程度:所谓后验概率,就是根据具体资料.先验概率.特定 ...

  3. HDU 4655 Cut Pieces 找规律+简单计数

    解法参考:http://blog.csdn.net/a601025382s/article/details/9840125 #include <cstdio> #include <c ...

  4. Android5.0新特性

    1.Activity转场动画 首先,把之前启动Activity的代码改成下面的写法: (如果低版本需要加注解@RequiresApi(api = Build.VERSION_CODES.LOLLIPO ...

  5. PHP上传多文件

    知识点: 一.$_FILES数组 ①.$_FILES['filename']['name']上传文件原名 ②.$_FILES['filename']['tmp_name']上传成功后的缓存文件名 ③. ...

  6. poj 1743 Musical Theme (后缀数组+二分法)

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 16162   Accepted: 5577 De ...

  7. Spark on Yarn——spark1.5.1集群配置

    写在前面: spark只是一种计算框架,如果要搭建集群要依托与一定的组织模式. 目前来说,Spark集群的组织形式有三种: 1.      Standalone:使用akka作为网络IO组件,mast ...

  8. [poj] 1269 [zoj] 1280 Interesting Lines || 求两直线交点

    POJ原题 ZOJ原题 多组数据.每次给出四个点,前两个点确定一条直线,后两个点确定一条直线,若平行则输出"NONE",重合输出"LINE",相交输出" ...

  9. [codeforces] 449C Jzzhu and Apples

    原题 质因数分解后贪心即可(最后贪2) #include<cstdio> #include<vector> #include<stack> #include< ...

  10. 【CF Round 439 B. The Eternal Immortality】

    time limit per test 1 second memory limit per test 256 megabytes input standard input output standar ...