• codeforces-600E


    链接:

    http://codeforces.com/problemset/problem/600/E

    题意:

    You are given a rooted tree with root in vertex 1. Each vertex is coloured in some colour.

    Let's call colour c dominating in the subtree of vertex v if there are no other colours that appear in the subtree of vertex v more times than colour c. So it's possible that two or more colours will be dominating in the subtree of some vertex.

    The subtree of vertex v is the vertex v and all other vertices that contains vertex v in each path to the root.
    求一个子数的众数和

    思路:

    考虑暴力算法,每次计算清零,复杂度n^2.
    启发式合并,先处理出每个字节点的重儿子,和子树大小。
    我们优先遍历每个子树的轻儿子,但是每次处理完后不保存记录的信息。
    最后一次遍历重儿子,因为只剩重儿子,所以这个重儿子不需要清楚信息。
    再统计子树的根节点时还要计算一边轻儿子。
    总复杂度nlogn。不会证(逃

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int MAXN = 1e5+10;
    const int MOD = 1e9+7;
    const int INF = 1e9+10;
    
    int n, num;
    int size[MAXN], son[MAXN], dfn[MAXN];
    int a[MAXN], b[MAXN], c[MAXN], col[MAXN];
    LL mx, now, ans[MAXN];
    vector<int> G[MAXN];
    
    void dfs(int x, int fa)
    {
        //计算子树大小,找重儿子
        size[x] = 1, dfn[x] = ++num;
        for (auto &y: G[x])
        {
            if (y == fa) continue;
            dfs(y, x);
            size[x] += size[y];
            son[x] = size[y] > size[son[x]] ? y : son[x];
        }
    }
    
    void add(int x)
    {
        if (++c[x] > mx) mx = c[x], now = 0;
        if (c[x] == mx) now += x;
    }
    
    void solve(int x, int fa, int k)
    {
        for (auto &y: G[x]) if (y != fa && y != son[x])
            solve(y, x, 0);
        if (son[x]) solve(son[x], x, 1);
        for (auto &y: G[x]) if (y != fa && y != son[x])
            for (int i = 0;i < size[y];i++) add(a[dfn[y]+i]);
        add(a[dfn[x]]);
        ans[x] = now;
        if (!k) for (int i = mx = now = 0;i < size[x];i++) c[a[dfn[x]+i]] = 0;
    }
    
    int main()
    {
        //dsu on tree 启发式合并
        ios::sync_with_stdio(stdin);
        cin.tie(0), cout.tie(0);
        num = 0;
        cin >> n;
        for (int i = 1;i <= n;i++)
            cin >> col[i];
        for (int i = 1;i < n;i++)
        {
            int u, v;
            cin >> u >> v;
            G[u].push_back(v);
            G[v].push_back(u);
        }
        dfs(1, 0);
        for (int i = 1;i <= n;i++) a[dfn[i]] = col[i];
        solve(1, 0, 1);
        for (int i = 1;i <= n;i++)
            cout << ans[i] << ' ' ;
    
        return 0;
    }
    
    
  • 相关阅读:
    通过WCF引用ListData.svc查询,更新数据
    SharePoint2010 BCS搜索结果的标题
    多个Finder方法的外部内容类型
    SharePoint 2010 中的BCS身份验证模式
    使用Visual Studio工作流发布SharePoint网页
    PerformancePoint Services故障排除
    使用SharePoint 2010模式对话框
    在自定义字段类型的CAML中使用AJAX jQuery
    扩展Visual Studio 2010服务器资源管理器中的SharePoint结点
    BCS配置文件页、爬网与搜索
  • 原文地址:https://www.cnblogs.com/YDDDD/p/12223665.html
Copyright © 2020-2023  润新知