zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 2 E. Lomsat gelral(dsu)

    题目链接

    题意:给你一棵以1为根n个点的树,问你以i为根的子树的众数和是多少

    思路:dsu是一种优化暴力的手段 首先进行轻重链剖分 然后只记录重链的信息 轻链的信息就直接暴力查找 经过证明这样复杂度可以是nlogn。

    #include<bits/stdc++.h>
    #define ll long long int
    using namespace std;
    inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
    int moth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    int dir[4][2]={1,0 ,0,1 ,-1,0 ,0,-1};
    int dirs[8][2]={1,0 ,0,1 ,-1,0 ,0,-1, -1,-1 ,-1,1 ,1,-1 ,1,1};
    const int inf=0x3f3f3f3f;
    const ll mod=1e9+7;
    const int N=100007;
    vector<int> G[N];
    int col[N],dp[N],son[N];
    ll cnt[N],ans[N];
    ll maxx=-inf,sum=0;
    int po;
    void dfs(int u,int fa){
        dp[u]=1;
        for(int i=0;i<G[u].size();i++){
            int v=G[u][i];
            if(v==fa) continue;
            dfs(v,u);
            dp[u]+=dp[v];
            if(dp[v]>dp[son[u]]) son[u]=v; //找重儿子 
        }
    }
    void add(int u,int fa,int w){
        cnt[col[u]]+=w;
        if(cnt[col[u]]>maxx) maxx=cnt[col[u]],sum=col[u];
        else if(cnt[col[u]]==maxx) sum+=col[u];
        for(int i=0;i<G[u].size();i++){
            int v=G[u][i];
            if(v==fa||v==po) continue;
            add(v,u,w);
        }
    }
    void dfss(int u,int fa,int opt){
        for(int i=0;i<G[u].size();i++){
            int v=G[u][i];
            if(v==fa) continue;
            if(son[u]!=v) dfss(v,u,0); //优先遍历轻儿子 
        }
        if(son[u]) dfss(son[u],u,1),po=son[u];//po是标记当重链的重儿子 在算当前节点时可以不用遍历重儿子 
        add(u,fa,1);
        po=0;
        ans[u]=sum;
        if(!opt) add(u,fa,-1),maxx=-inf,sum=0; //消除轻儿子的影响 
    }
    int main(){
        ios::sync_with_stdio(false);
        int n; cin>>n;
        for(int i=1;i<=n;i++){
            cin>>col[i];
        }
        for(int i=1;i<=n-1;i++){
            int u,v; cin>>u>>v;
            G[u].push_back(v);
            G[v].push_back(u);
        }
        dfs(1,0); dfss(1,0,1);
        for(int i=1;i<=n;i++)
            cout<<ans[i]<<" ";
        return 0;
    }
  • 相关阅读:
    PAT 1010. 一元多项式求导 (25)
    PAT 1009. 说反话 (20) JAVA
    PAT 1009. 说反话 (20)
    PAT 1007. 素数对猜想 (20)
    POJ 2752 Seek the Name, Seek the Fame KMP
    POJ 2406 Power Strings KMP
    ZOJ3811 Untrusted Patrol
    Codeforces Round #265 (Div. 2) 题解
    Topcoder SRM632 DIV2 解题报告
    Topcoder SRM631 DIV2 解题报告
  • 原文地址:https://www.cnblogs.com/wmj6/p/11127301.html
Copyright © 2011-2022 走看看