zoukankan      html  css  js  c++  java
  • 《洛谷CF600E Lomsat gelral》

    题意:统计每个子树里的最多颜色编号和。

    注意的是,如果有多个颜色编号次数一样,那么都要加上。所以这里会爆int。

    思路:dsu on tree的模板题吧。

    对于重儿子保留操作,轻儿子删去。

    也就是说暴力的一种优化,复杂度nlogn,不会证明。

    一些细节:注意的是,所谓轻儿子的清空,就是对统计做一次-1.这样就清空了,那么显然重儿子在统计里也要被排除。

    // Author: levil
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<LL,int> pii;
    const int N = 1e5+5;
    const int M = 1e5+5;
    const LL Mod = 199999;
    #define rg register
    #define pi acos(-1)
    #define INF 1e9
    #define CT0 cin.tie(0),cout.tie(0)
    #define IO ios::sync_with_stdio(false)
    #define dbg(ax) cout << "now this num is " << ax << endl;
    namespace FASTIO{
        inline LL read(){
            LL x = 0,f = 1;char c = getchar();
            while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
            while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
            return x*f;
        }
        void print(int x){
            if(x < 0){x = -x;putchar('-');}
            if(x > 9) print(x/10);
            putchar(x%10+'0');
        }
    }
    using namespace FASTIO;
    void FRE(){/*freopen("data1.in","r",stdin);
    freopen("data1.out","w",stdout);*/}
    
    int n,c[N],son[N],ssize[N],cnt[N],Son = 0;
    LL ans[N],Maxx = 0,sum = 0;
    vector<int> G[N];
    void dfs(int u,int fa)
    {
        ssize[u] = 1;
        for(auto v : G[u])
        {
            if(v == fa) continue;
            dfs(v,u);
            ssize[u] += ssize[v];
            if(ssize[v] > ssize[son[u]]) son[u] = v;
        }
    }
    void slove(int u,int fa,int val,int Son)
    {
        cnt[c[u]] += val;
        if(cnt[c[u]] > Maxx) Maxx = cnt[c[u]],sum = c[u];
        else if(cnt[c[u]] == Maxx) sum += c[u];
        for(auto v : G[u])
        {
            if(v == fa || v == Son) continue;
            slove(v,u,val,Son);
        }
    }
    void dfs1(int u,int fa,int opt)
    {
        for(auto v : G[u])
        {
            if(v == fa || v == son[u]) continue;
            dfs1(v,u,0);
        }
        if(son[u]) dfs1(son[u],u,1),Son = son[u];
        slove(u,fa,1,Son);
        Son = 0;
        ans[u] = sum;
        if(opt == 0) slove(u,fa,-1,Son),Maxx = sum = 0;//不是重儿子,清空,点数也要删去。但是保留重儿子的贡献
    }
    int main()
    {
        n = read();
        for(rg int i = 1;i <= n;++i) c[i] = read();
        for(rg int i = 1;i < n;++i)
        {
            int x,y;x = read(),y = read();
            G[x].push_back(y);
            G[y].push_back(x);
        }
        dfs(1,0);
        dfs1(1,0,0);
        for(rg int i = 1;i <= n;++i) printf("%lld%c",ans[i],i == n ? '
    ' : ' ');
        system("pause");
    }
    View Code
  • 相关阅读:
    家庭记账本---开发进度1
    HDOJ 1004--Let the Balloon Rise
    DP HDIJ1421 搬宿舍
    动态规划之最长公共子序列
    和最大的子序列之二
    和最大的子序列之一
    动态规划之一最长上升子序列LIS
    动态规划之一数塔
    动态规划之一ones
    动态规划实例
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/13605503.html
Copyright © 2011-2022 走看看