You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

65 lines
1.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, M = N << 1;
#define int long long
#define endl "\n"
// 链式前向星
int e[M], h[N], idx, w[M], ne[M];
void add(int a, int b, int c = 0) {
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}
int f[N], g[N], son[N], ans[N];
int n, mod;
vector<int> val[N], pre[N], suc[N];
void dfs1(int u, int fa) {
f[u] = 1; // 底为1方便累乘
val[u].push_back(1); // 用一个动态数组,记录都是哪些数字在累乘。
// f[u]是累乘并取模的结果val[u]是都是哪些数字累乘的,一个是结果,一个是过程
for (int i = h[u]; ~i; i = ne[i]) {
int v = e[i];
if (v == fa) continue;
dfs1(v, u);
son[u]++; // 记录u有多少个儿子,注意不是习惯的有多少个子孙节点,而是儿子有多少个
val[u].push_back(f[v] + 1); // 记录过程
f[u] = f[u] * (f[v] + 1) % mod; // 记录结果
}
}
void dfs2(int u, int fa) {
ans[u] = f[u] * g[u] % mod;
pre[u].resize(son[u] + 2);
suc[u].resize(son[u] + 2);
pre[u][0] = suc[u][son[u] + 1] = 1;
// 前缀积
for (int i = 1; i <= son[u]; i++) pre[u][i] = pre[u][i - 1] * val[u][i] % mod;
// 后缀积
for (int i = son[u]; i >= 1; i--) suc[u][i] = suc[u][i + 1] * val[u][i] % mod;
int m = 0;
for (int i = h[u]; ~i; i = ne[i]) {
int v = e[i];
if (v == fa) continue;
m++;
g[v] = g[u] * pre[u][m - 1] % mod * suc[u][m + 1] % mod;
g[v] = (g[v] + 1) % mod;
dfs2(v, u);
}
}
signed main() {
// 初始化链式前向星
memset(h, -1, sizeof h);
cin >> n >> mod;
for (int i = 1; i < n; i++) {
int a, b;
cin >> a >> b;
add(a, b), add(b, a);
}
dfs1(1, 0);
g[1] = 1;
dfs2(1, 0);
for (int i = 1; i <= n; i++) cout << ans[i] << endl;
}