[dsu on tree]Special_Containment_Procedures
Posted yuxiaoze
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[dsu on tree]Special_Containment_Procedures相关的知识,希望对你有一定的参考价值。
题目描述
TAIYU把OJ上的所有题都建成了一棵树(虽然我也不知道他怎么建的)在一颗子树里面的题大多都有一些共同点。
当然,1号点是根结点,(一猜就是A+B Problem) 每一道题都有一个难度系数 ai 定义f(i)为i的子树的出现次数最
多的难度的和。 举个例子:如果i子树内题目的难度为:
1 1 2 3 3 5
则f(i)等于1+3=4; 你需要输出 f(1),f(2),f(3),f(n)
输入描述
第一行一个整数表示n 第二行n个数,表示i节点的难度系数ci 第3行至第n+1行,每行2个数u,v,表示u,v之间连边
输出描述
一行n个数,第i个数表示f(i)
Solution
dsu on tree https://www.cnblogs.com/zwfymqz/p/9683124.html
或 线段树合并 https://www.cnblogs.com/Mychael/p/8665589.html
都是nlogn 直接启发式合并n*logn*logn 貌似也能过
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 const int N=1e5+5; 5 int n,c[N],ans[N]; 6 int num,last[N],nxt[2*N],ver[2*N]; 7 inline void add(int x,int y) {nxt[++num]=last[x]; last[x]=num; ver[num]=y;} 8 9 int fa[N],siz[N],son[N]; 10 void build(int x) 11 {siz[x]=1; 12 for(int i=last[x];i;i=nxt[i]) 13 {int y=ver[i]; 14 if(y==fa[x]) continue; 15 fa[y]=x; build(y); 16 siz[x]+=siz[y]; 17 if(siz[son[x]]<siz[y]) son[x]=y; 18 } 19 } 20 int maxx,sum,cnt[N]; 21 void update(int x,int son,int v) 22 {cnt[c[x]]+=v; 23 if(cnt[c[x]]>maxx) maxx=cnt[sum=c[x]]; 24 else if(cnt[c[x]]==maxx)sum+=c[x]; 25 for(int i=last[x];i;i=nxt[i]) 26 {int y=ver[i]; 27 if(y!=fa[x] && y!=son) 28 update(y,0,v); 29 } 30 } 31 void dfs(int x) 32 {for(int i=last[x];i;i=nxt[i]) 33 {int y=ver[i]; 34 if(y!=son[x] && y!=fa[x]) dfs(y); 35 } 36 if(son[x]) dfs(son[x]); 37 update(x,son[x],1); 38 ans[x]=sum; 39 if(son[fa[x]]!=x) update(x,0,-1),maxx=sum=0; 40 } 41 int main() 42 { 43 scanf("%d",&n); int x,y; 44 for(int i=1;i<=n;i++) scanf("%d",&c[i]); 45 46 for(int i=1;i<=n;i++) {scanf("%d%d",&x,&y); add(x,y); add(y,x); } 47 48 build(1); dfs(1); 49 for(int i=1;i<=n;i++) printf("%d ",ans[i]); 50 return 0; 51 }
以上是关于[dsu on tree]Special_Containment_Procedures的主要内容,如果未能解决你的问题,请参考以下文章