思路
有根树的树上拓扑序问题。
对于每一个 ,以 为根。
树上拓扑序问题有一个公式,为 ( 指的是一个子树点的个数)。
可以先把 的逆元数组 给预处理。
设 为根为 时的答案。
先 DFS 一遍求出以 为根的 。
接下来的 用换根即可。
即 。
最后输出一下 即可。
复杂度 。
:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const int N = 2e5 + 10;
ll inv[N], sz[N], ans[N];
vector<int> G[N];
int n;
void dfs1(int u, int fa) {
sz[u] = 1;
for (auto v : G[u]) {
if (v == fa) continue;
dfs1(v, u);
sz[u] += sz[v];
}
ans[1] = ans[1] * inv[sz[u]] % mod;
}
void dfs2(int u, int fa) {
for (auto v : G[u]) {
if (v == fa) continue;
ans[v] = ans[u] * sz[v] % mod * inv[n - sz[v]] % mod;
dfs2(v, u);
}
}
int main() {
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);
}
inv[1] = 1;
for (int i = 2; i <= n; i++) {
inv[i] = (mod - mod / i) * inv[mod % i] % mod;
}
ans[1] = 1;
for (int i = 1; i <= n; i++) {
ans[1] = ans[1] * i % mod;
}
dfs1(1, 0);
dfs2(1, 0);
for (int i = 1; i <= n; i++) {
printf("%lld\n", ans[i]);
}
return 0;
}