ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

树上启发式合并

2022-07-22 11:42:28  阅读:172  来源: 互联网

标签:cnt int sum 合并 son num maxn 启发式 树上


模板

#include <iostream>
#include <cstdio>
using namespace std;
const int N = 100010;
int n, c[N], head[N], ver[N << 1], nex[N << 1], tot, cnt[N], num[N], siz[N], son[N], L[N], R[N], dfn, pos[N], maxn;
long long sum[N], ans[N];
inline void add (int x, int y) {
    ver[++ tot] = y;
    nex[tot] = head[x];
    head[x] = tot;
}
void dfs1 (int x, int fa) {
    L[x] = ++ dfn;
    pos[dfn] = x;
    siz[x] = 1;
    for (int i = head[x]; i; i = nex[i]) {
        int y = ver[i];
        if (y == fa) continue;
        dfs1(y, x);
        siz[x] += siz[y];
        if (!son[x] || siz[y] > siz[son[x]]) son[x] = y;
    }
    R[x] = dfn;
}
inline void addans (int x) {
    sum[cnt[c[x]]] -= c[x];
    num[cnt[c[x]]] --;
    cnt[c[x]] ++;
    num[cnt[c[x]]] ++;
    maxn = max(maxn, cnt[c[x]]);
    sum[cnt[c[x]]] += c[x];
}
inline void delans (int x) {
    sum[cnt[c[x]]] -= c[x];
    num[cnt[c[x]]] --;
    if (!num[cnt[c[x]]] && maxn == cnt[c[x]]) maxn --;
    cnt[c[x]] --;
    num[cnt[c[x]]] ++;
    sum[cnt[c[x]]] += c[x];
}
void dfs2 (int x, int fa, int flag) {
    for (int i = head[x]; i; i = nex[i]) {
        int y = ver[i];
        if (y == fa || y == son[x]) continue;
        dfs2(y, x, 0);
    }
    if (son[x]) dfs2(son[x], x, 1);
    for (int i = head[x]; i; i = nex[i]) {
        int y = ver[i];
        if (y == fa || y == son[x]) continue;
        for (int j = L[y]; j <= R[y]; j ++)
            addans(pos[j]);
    }
    addans(x);
    ans[x] = sum[maxn];
    if (flag) return;
    for (int i = L[x]; i <= R[x]; i ++)
        delans(pos[i]);
}
int main () {
    scanf("%d", &n);
    for (int i = 1; i <= n; i ++) scanf("%d", &c[i]);
    for (int i = 1; i < n; i ++) {
        int x, y;
        scanf("%d%d", &x, &y);
        add(x, y);
        add(y, x);
    }
    dfs1(1, 0);
    dfs2(1, 0, 1);
    for (int i = 1; i <= n; i ++) printf("%lld ", ans[i]);
    return 0;
}

标签:cnt,int,sum,合并,son,num,maxn,启发式,树上
来源: https://www.cnblogs.com/duoluoluo/p/16505131.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有