[dsu on tree] Codeforces 600E Lomsat gelral

题目大意

  • 给出一个树,求出每个节点的子树中出现次数最多的颜色的编号和

题解

  • 这是一道dsu on tree的模板题
  • 那dsu on tree到底是个啥东西呢
  • dsu on tree是一种类似暴力的做法,用来解决一类树上询问的问题。一般有两种特征:①只有对子树询问 ②没有修改操作 

    dsu on tree运用了类似轻重链剖分把复杂度给降到O(nlogn)

    算法流程:先dfs处理出每个父节点的重轻儿子,然后统计的时候,先递归处理每个轻儿子的贡献,同时消除递归产生的影响,然后递归重儿子,不消除递归的影响,再统计所有轻儿子对答案的影响,最后更新该节点的答案和删除所有轻儿子对答案的影响

    我们来证明一下这个东东的复杂度,我们考虑一个点会被访问几次,发现只有两种情况,一种是暴力统计轻边的时候访问到,因为一个点到根的轻边数量不会多于logn条,所以次数<logn;第二种是通过重边被访问到显然每个点只会被访问一次。综上所述,如果一个点所贡献的复杂度为O(1)的话,总复杂度为O(nlogn)

     
  • 然后我们就可以发现用上面这个东西,可以很暴力的解决这个问题

代码

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <vector>
 5 #define N 100010
 6 #define ll long long
 7 using namespace std;
 8 int n,mx,Son,col[N],son[N],sz[N],cnt[N];
 9 ll sum,ans[N];
10 vector<int>Q[N];
11 int read()
12 {
13     char c=getchar(); int x=0,f=1;
14     while (c<'0'||c>'9') { if(c == '-') f=-1;c=getchar(); }
15     while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
16     return x*f;
17 }
18 void add(int x,int fa,int val)
19 {
20     cnt[col[x]]+=val;
21     if (cnt[col[x]]>mx) mx=cnt[col[x]],sum=col[x]; else if (cnt[col[x]]==mx) sum+=(ll)col[x];
22     for (int i=0;i<Q[x].size();i++) if (Q[x][i]!=fa&&Q[x][i]!=Son) add(Q[x][i],x,val);
23 }
24 void dfs1(int x,int fa)
25 {
26     sz[x]=1;
27     for (int i=0;i<Q[x].size();i++)
28         if (Q[x][i]!=fa)
29         {
30             dfs1(Q[x][i],x),sz[x]+=sz[Q[x][i]];
31             if (sz[Q[x][i]]>sz[son[x]]) son[x]=Q[x][i];
32         }
33 }
34 void dfs2(int x,int fa,int op)
35 {
36     for (int i=0;i<Q[x].size();i++) if (Q[x][i]!=fa&&Q[x][i]!=son[x]) dfs2(Q[x][i],x,0);
37     if (son[x]) dfs2(son[x],x,1),Son=son[x];
38     add(x,fa,1),Son=0,ans[x]=sum;
39     if (!op) add(x,fa,-1),sum=0,mx=0;
40 }
41 int main()
42 {
43     n=read();
44     for (int i=1;i<=n;i++) col[i]=read();
45     for (int i=1,x,y;i<n;i++) x=read(),y=read(),Q[x].push_back(y),Q[y].push_back(x);
46     dfs1(1,0),dfs2(1,0,0);
47     for (int i=1;i<=n;i++) printf("%lld ",ans[i]);
48 }
原文地址:https://www.cnblogs.com/Comfortable/p/11185918.html