#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod=1e9+7;
const int maxn=1e6+10;
int read() {
int X=0,w=1; char c=getchar();
while (c<'0'||c>'9') { if (c=='-') w=-1; c=getchar(); }
while (c>='0'&&c<='9') X=X*10+c-'0',c=getchar();
return X*w;
}
int n;
vector<int> G[maxn];
LL dp[maxn],ans[maxn],sta[maxn];
int pre[maxn];
LL inv(LL x)
{
LL ans=1;
LL tmp=x%mod;
LL m=mod-2;
while(m){
if(m&1){
ans=ans*tmp;
ans%=mod;
}
tmp*=tmp;
tmp%=mod;
m/=2;
}
return ans%mod;
}
void dfs1(int u,int fa)
{
pre[u]=fa;
dp[u]=1;
int len=G[u].size();
for(int i=0;i<len;i++){
int to=G[u][i];
if(to==fa)continue;
dfs1(to,u);
dp[u]*=(dp[to]+1);
dp[u]%=mod;
}
}
void dfs2(int u,int fa)
{
int len=G[u].size();
if(fa!=0){
if((dp[u]+1)%mod==0){//特殊情况,暴力处理
LL num=sta[fa]+1;
for(int i=0;i<G[fa].size();i++){
int v=G[fa][i];
if(v==pre[fa]||v==u)continue;
num*=(dp[v]+1);
num%=mod;
}
sta[u]=num;
ans[u]=(num+1)*dp[u]%mod;
}
else{
LL num=ans[fa]*inv(dp[u]+1)%mod;
sta[u]=num;
ans[u]=(num+1)*dp[u]%mod;
}
}
for(int i=0;i<len;i++){
if(G[u][i]!=fa){
dfs2(G[u][i],u);
}
}
}
int main()
{
n=read();
int u,v;
for(int i=1;i<=n-1;i++){
u=read();v=read();
//dp[i]=1;
G[u].push_back(v);G[v].push_back(u);
}
//dp[n]=1;
dfs1(1,0);
ans[1]=dp[1];
dfs2(1,0);
for(int i=1;i<=n;i++){
printf("%lld\n",ans[i]);
}
return 0;
}
https://ac.nowcoder.com/acm/problem/19782(换根树形dp求包含某个点的连通点集的数量(注意对0的讨论))
最新推荐文章于 2020-07-07 23:03:27 发布