zoukankan      html  css  js  c++  java
  • CF600E Lomsat gelral

    题意

    给你一棵有(n)个点的树 $ n leq 10^5$,树上每个节点都有一种颜色 (a_i),让你求每个点子树出现最多的颜色的编号(多个就求和)

    思路

    考虑暴力怎么写:遍历每个节点—把子树中的所有颜色暴力统计出来算答案—清空—继续递归

    这肯定是(O(n^2))的。

    (dsu space on space tree)巧妙的利用了轻重链的性质,把复杂度降到了(O(nlogn))

    (dsu space on space tree)的算法流程是这样的:

    对于节点(i)

    • 遍历每一个节点
    • 递归解决所有的轻儿子,同时消除递归产生的影响
    • 递归重儿子,不消除递归的影响
    • 统计所有轻儿子对答案的影响
    • 更新该节点的答案
    • 删除所有轻儿子对答案的影响

    这样子重儿子的子树就避免了重复操作
    至于复杂度的证明,就算了吧

    #include <bits/stdc++.h>
    const int N=100005;
    int edge,to[N<<1],last[N],Next[N<<1],size[N],son[N],Mx,cnt[N],a[N],n,x,y,Son; 
    long long Ans,ans[N];
    void add(int x,int y){
    	to[++edge]=y;
    	Next[edge]=last[x];
    	last[x]=edge;
    }
    void dfs(int x,int fa){
    	size[x]=1;
    	for (int i=last[x];i;i=Next[i])
    	if (to[i]!=fa){
    		dfs(to[i],x);
    		if (size[to[i]]>size[son[x]]) son[x]=to[i];
    		size[x]+=size[to[i]];
    	}
    }
    void add(int x,int fa,int opt){
    	cnt[a[x]]+=opt;
    	if (cnt[a[x]]>Mx) Mx=cnt[a[x]],Ans=a[x];
    	else if (cnt[a[x]]==Mx) Ans+=a[x];
    	for (int i=last[x];i;i=Next[i])
    	if (to[i]!=fa && to[i]!=Son)
    		add(to[i],x,opt);
    }
    void dfs2(int x,int fa,int opt){
    	for (int i=last[x];i;i=Next[i])
    	if (to[i]!=fa){
    		if (to[i]!=son[x]) dfs2(to[i],x,0);
    	}
    	if (son[x]) dfs2(son[x],x,1),Son=son[x];
    	add(x,fa,1);
    	Son=0;
    	ans[x]=Ans;
    	if (!opt) add(x,fa,-1),Mx=0,Ans=0;
    }
    int main(){
    	scanf("%d",&n);
    	for (int i=1;i<=n;i++)
    		scanf("%d",&a[i]);
    	for (int i=1;i<n;i++){
    		scanf("%d%d",&x,&y);
    		add(x,y),add(y,x);
    	}
    	dfs(1,0);
    	dfs2(1,0,1);
    	for (int i=1;i<=n;i++) printf("%I64d ",ans[i]);
    }
    

    注意

    编号和会爆(int)

    * 生而自由 爱而无畏 *
  • 相关阅读:
    CSU 1333 Funny Car Racing
    FZU 2195 检查站点
    FZU 2193 So Hard
    ZOJ 1655 FZU 1125 Transport Goods
    zoj 2750 Idiomatic Phrases Game
    hdu 1874 畅通工程续
    hdu 2489 Minimal Ratio Tree
    hdu 3398 String
    洛谷 P2158 [SDOI2008]仪仗队 解题报告
    POJ 1958 Strange Towers of Hanoi 解题报告
  • 原文地址:https://www.cnblogs.com/flyfeather6/p/10964243.html
Copyright © 2011-2022 走看看