思路

应该是个比较基础的换根吧...我相信我再做几个换根应该都能做出来的!
表示这个节点的联通点集的数量.
那么一个很显然的一个方程就是其中的子节点.这个点的联通点集数量就是子节点的联通点集数量的选取,以及不选取的方案数的乘积.
由此我们可以的算出一个点的答案是多少.
然后考虑换根,的子节点的答案怎么算呢?其实挺简单的,思考变成的子节点,以前的是不是会少了这个点的答案呢?所以当然这不够,考虑已经成为了根节点,那么不含这部分的值是拿这个值即可.
对于的没有逆元,这时暴力算即可.

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5;
const int mod=1e9+7;
ll dp[N],ans[N];
vector<int>g[N];
ll qp(ll a,ll b)
{
        ll res=1;
        while(b)
        {
                if(b&1)        res=res*a%mod;
                a=a*a%mod;
                b>>=1;
        }
        return res;
}

void dfs(int u,int fa)
{
        dp[u]=1;
        for(int v:g[u])
        {
                if(v==fa)    continue;
                dfs(v,u);
                dp[u]=dp[u]*(dp[v]+1)%mod;
        }
}

void DFS(int u,int fa)
{
        if(fa==-1)    ans[u]=dp[u];
        else if((dp[u]+1)%mod==0)
        {
                dfs(u,u);
                ans[u]=dp[u];
        }
        else    ans[u]=(ans[fa]%mod*qp(dp[u]+1,mod-2)+1)%mod*(dp[u])%mod;
        for(int v:g[u])
        {
                if(v==fa)    continue;
                DFS(v,u);
        }
}

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