题意:
给与一棵n个节点的树,求每个点的连通点集的数量?

思路:
树形结构+换根
dp[i]表示以i为根且包括i的这棵子树连通点集的数量。
ans[i]表示包括i的连通点集的数量,既结果。
父节点u与子节点v:
dp[u]=图片说明 (dp[v]+1) * dp[u];(v为u的子节点)
换根时:
ans[v]=((ans[u]/(dp[v]+1))+1)*dp[v];
注意:0不能求逆元,所以当(dp[v]+1)%inf=0时,你就需要重新计算一下该点的结果。

代码:

#include <bits/stdc++.h>
typedef long long ll;

using namespace std;

const ll inf=1e9+7;

inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}

ll dp[1000005], ans[1000005];

vector<int> g[1000005];

void dfs(int v, int f)
{
    dp[v]=1;
    for(int i=0;i<g[v].size();i++)
    {
        if(g[v][i]!=f)
        {
            dfs(g[v][i],v);
        }
        else
        {
            continue;
        }
        dp[v]=((dp[g[v][i]]+1)*dp[v])%inf;
    }
}

ll fun(ll n,ll m)
{
   ll s=1;
   while(m)
   {
       if(m&1)
       {
           s=s*n%inf;
       }
       n=n*n%inf;
       m=m/2;
   }
   return s;
}

void dfs1(int v, int f)
{
    if(f!=-1)
    {
        if((dp[v]+1)%inf==0)
        {
            dfs(v,-1);
            ans[v]=dp[v];
        }
        else
        {
            ans[v]=((ans[f]*fun((dp[v]+1),inf-2)%inf)+1)*dp[v]%inf;
        }
    }
    else
    {
        ans[v]=dp[v];
    }
    for(int i=0;i<g[v].size();i++)
    {
        if(g[v][i]!=f)
        {
            dfs1(g[v][i],v);
        }
    }
}

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=2;i<=n;i++)
    {
        int u=read(), v=read();
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs(1,-1);
    dfs1(1,-1);
    for(int i=1;i<=n;i++)
    {
        printf("%lld\n",ans[i]);
    }
    return 0;
}