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;
    }
  • 相关阅读:
    【BZOJ 2124】【CodeVS 1283】等差子序列
    【BZOJ 1036】【ZJOI 2008】树的统计Count
    【BZOJ 1901】【ZJU 2112】Dynamic Rankings
    【BZOJ 3924】【ZJOI 2015】幻想乡战略游戏
    【BZOJ 4103】【THUSC 2015】异或运算
    【BZOJ 4513】【SDOI 2016】储能表
    【HDU 3622】Bomb Game
    【BZOJ 3166】【HEOI 2013】Alo
    【BZOJ 3530】【SDOI 2014】数数
    【BZOJ 4567】【SCOI 2016】背单词
  • 原文地址:https://www.cnblogs.com/wmj6/p/11127301.html
Copyright © 2011-2022 走看看