• codeforces600E. Lomsat gelral(dsu on tree笔记)


    知识前驱:树链剖分

    codeforces600E. Lomsat gelral

    题意:给出一个树,求出每个节点的子树中出现次数最多的颜色的编号和

    分析:递归求解,对于一棵树,求出他的所有子树的颜色编号次数加上它本身,找到最大即是它的答案。对于他的兄弟来说,应该将计数器清0并同过程求解,在最后一个兄弟计算完毕后,此时计数器可不清0,再次统计该兄弟的兄弟(即该兄弟的同深度其他节点),便求出了它的父亲的所有子树的颜色编号次数,再加上它本身,找到最大即是它父亲的答案。

    dsu on tree在这样一个暴力的过程中,将重儿子作为上述的最后一个兄弟,此时计数器不清0,再暴力统计轻儿子以获得答案。

     1 #pragma GCC optimize(3, "Ofast", "inline")
     2  
     3 #include <bits/stdc++.h>
     4  
     5 #define start ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
     6 #define ll long long
     7 #define LL long long
     8 #define uu unsigned int
     9 #define int ll
    10 #define ls st<<1
    11 #define rs st<<1|1
    12 using namespace std;
    13 const int maxn = (ll) 1e6 + 5;
    14 const int mod = 1000000007;
    15 const int inf = 0x3f3f3f3f;
    16  
    17 int son[maxn], siz[maxn], cnt[maxn], col[maxn], ans[maxn];
    18 vector<int> v[maxn];
    19  
    20 void dfs(int x, int pre) {
    21     siz[x] = 1;
    22     for (auto &to:v[x]) {
    23         if (to == pre)
    24             continue;
    25         dfs(to, x);
    26         siz[x] += siz[to];
    27         if (siz[to] > siz[son[x]])
    28             son[x] = to;
    29     }
    30 }
    31  
    32 int sum, maxx, now;
    33  
    34 void add(int x, int pre, int val) {
    35     cnt[col[x]] += val;
    36     if (cnt[col[x]] > maxx) {
    37         maxx = cnt[col[x]];
    38         sum = col[x];
    39     } else if (cnt[col[x]] == maxx)
    40         sum += col[x];
    41     for (auto &to:v[x]) {
    42         if (to == now || to == pre)
    43             continue;
    44         add(to, x, val);
    45     }
    46 }
    47  
    48 void dfs2(int x, int pre, bool ord) {
    49     for (auto &to:v[x]) {
    50         if (to == pre || to == son[x])
    51             continue;
    52         dfs2(to, x, false);
    53     }
    54     if (son[x]) {
    55         dfs2(son[x], x, true);
    56         now = son[x];
    57     }
    58     add(x, pre, 1);
    59     ans[x] = sum;
    60     if (!ord) {
    61         now = 0;
    62         add(x, pre, -1);
    63         sum = 0;
    64         maxx = 0;
    65     }
    66 }
    67  
    68 signed main() {
    69     start;
    70     int n;
    71     cin >> n;
    72     for (int i = 1; i <= n; ++i)
    73         cin >> col[i];
    74     for (int i = 1; i < n; ++i) {
    75         int x, y;
    76         cin >> x >> y;
    77         v[x].push_back(y);
    78         v[y].push_back(x);
    79     }
    80     dfs(1, 0);
    81     dfs2(1, 0, 0);
    82     for (int i = 1; i <= n; ++i)
    83         cout << ans[i] << ' ';
    84     return 0;
    85 }
  • 相关阅读:
    equa与==的区别
    使用Log4j进行日志操作
    动态代理的步骤
    批量插入使用SqlBulkCopy
    SQL之开窗函数二——在复杂场景中的实际运用
    SQL Server数据类型详解
    SQL Server遍历表的几种方法
    SQL Server之表变量
    SQL Server之字符串处理函数
    SQL Server之String_Split函数(SQL Server2016版本以上使用)
  • 原文地址:https://www.cnblogs.com/F-Mu/p/11456220.html
Copyright © 2020-2023  润新知