标签:math 节点 getc name lin set 特殊情况 blog algorithm
https://ac.nowcoder.com/acm/contest/6226/C
、
修修去年种下了一棵树,现在它已经有n个结点了。
修修非常擅长数数,他很快就数出了包含每个点的连通点集的数量。
澜澜也想知道答案,但他不会数数,于是他把问题交给了你。
换根dp
res = 1 ;
for(auto t : v[u]) {
if(t == x ) continue ;
res = res * (dp[t] + 1) % mod ;
}
发现dp[f] 这个还包含了dp[u] ,因为第一次dfs的时候,dp[u]只包含子孩子节点的贡献, 现在f节点的孩子节点u变成了根节点,如果算u节点的时候还用dp[u] *= dp[f] + 1, 那这肯定错误 , 所以就开一个数组sta[u]存一下当前节点从父亲节点那里传出来的值,这样肯定不会错误,因为在树中每个节点只有一个父亲节点,传出来的时候也只会一对一的传。那么算dp[u]不包含x节点贡献的时候,对于u的父亲节点f的贡献就是sta[u] + 1
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <unordered_map>
#include <vector>
#include <map>
#include <list>
#include <queue>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <stack>
#include <set>
#pragma GCC optimize(3 , "Ofast" , "inline")
using namespace std ;
#define ios ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define x first
#define y second
typedef long long ll ;
const double esp = 1e-6 , pi = acos(-1) ;
typedef pair<int , int> PII ;
const int N = 1e6 + 10 , INF = 0x3f3f3f3f , mod = 1e9 + 7;
ll in()
{
ll x = 0 , f = 1 ;
char ch = getchar() ;
while(!isdigit(ch)) {if(ch == ‘-‘) f = -1 ; ch = getchar() ;}
while(isdigit(ch)) x = x * 10 + ch - 48 , ch = getchar() ;
return x * f ;
}
ll qmi(ll a, ll b)
{
ll res = 1 ;
while(b)
{
if(b & 1) res = res * a % mod ;
a = a * a % mod ;
b >>= 1 ;
}
return res ;
}
vector<int> v[N] ;
ll dp[N] , n ;
void dfs(int u , int f)
{
dp[u] = 1 ;
for(auto x : v[u]) {
if(x == f) continue ;
dfs(x , u) ;
dp[u] = (dp[u] * (dp[x] + 1) % mod) % mod ;
}
return ;
}
ll ans[N] , sta[N] ;
void dfs1(int u , int f , ll sum)
{
sum %= mod ;
ans[u] = 1ll * dp[u] * sum % mod ;
for(auto x : v[u]) {
if(x == f) continue ;
ll res = 1 ;
if((dp[x] + 1) % mod) {
res = (ans[u] * qmi(dp[x] + 1 , mod - 2) % mod) % mod ;
}
else {
res = sta[u] + 1 ;
for(auto t : v[u]) {
if(t == x || t == f) continue ;
res = res * (dp[t] + 1) % mod ;
}
}
sta[x] = res ;
dfs1(x , u , res + 1) ;
}
return ;
}
int main()
{
n = in() ;
for(int i = 1; i < n ;i ++ )
{
int a = in() , b = in() ;
v[a].push_back(b) , v[b].push_back(a) ;
}
dfs(1 , 0) ;
dfs1(1 , 0 , 1) ;
for(int i = 1; i <= n ;i ++ ) cout << ans[i] << endl ;
return 0 ;
}
/*
*/
标签:math 节点 getc name lin set 特殊情况 blog algorithm
原文地址:https://www.cnblogs.com/spnooyseed/p/13264345.html