【换根DP】Subtree
Subtree - 洛谷
题意:
思路:
Code:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int mxn=1e5+10;
const int mxv=1e5+10;
vector<int> G[mxn];
int N,P,u,v;
int f[mxn],g[mxn],son[mxn],pre[mxn],suf[mxn];
void dfs(int u,int fa){
f[u]=1;
for(auto v:G[u]){
if(v==fa) continue;
dfs(v,u);
f[u]*=(f[v]+1)%P;
f[u]%=P;
}
}
void dfs2(int u,int fa){
if(G[u].size()==1&&G[u][0]==fa) return;
int idx=0;
for(auto v:G[u]){
if(v==fa) continue;
son[++idx]=v;
}
pre[0]=suf[idx+1]=1;
for(int i=1;i<=idx;i++){
pre[i]=pre[i-1]*(f[son[i]]+1)%P;
}
for(int i=idx;i>=1;i--){
suf[i]=suf[i+1]*(f[son[i]]+1)%P;
}
for(int i=1;i<=idx;i++){
g[son[i]]=(pre[i-1]*suf[i+1]%P*g[u]%P+1ll)%P;
}
for(auto v:G[u]){
if(v==fa) continue;
dfs2(v,u);
}
}
void solve(){
cin>>N>>P;
for(int i=1;i<=N-1;i++){
cin>>u>>v;
G[u].push_back(v);
G[v].push_back(u);
}
dfs(1,0);
g[1]=1;
dfs2(1,0);
for(int i=1;i<=N;i++){
cout<<f[i]*g[i]%P<<'\n';
}
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int __=1;//cin>>__;
while(__--)solve();return 0;
}
优美版(重生之我是jiangly):
#include <bits/stdc++.h>
using i64 = long long;
using namespace std;
const int N = 1e5 + 10;
const int Inf = 1e18;
vector<int> adj[N];
int m;
int dp[N], dp2[N], num[N];
int pre[N], suf[N];
void dfs1(int u,int fa) {
dp[u] = 1;
for (auto v : adj[u]) {
if (v == fa) continue;
dfs1(v, u);
dp[u] = dp[u] * (dp[v] + 1) % m;
dp[u] %= m;
}
}
void dfs2(int u,int fa) {
if (adj[u].size() == 1 && adj[u][0] == fa) return;
int len = 0;
for (auto v : adj[u]) {
if (v == fa) continue;
num[++len] = v;
}
pre[0] = suf[len + 1] = 1;
for (int i = 1; i <= len; i ++) {
pre[i] = pre[i - 1] * (dp[num[i]] + 1) % m;
}
for (int i = len ; i >= 1; i --) {
suf[i] = suf[i + 1] * (dp[num[i]] + 1) % m;
}
for (int i = 1; i <= len; i ++) {
dp2[num[i]] = (pre[i - 1] * suf[i + 1] %m * dp2[u] %m + 1) % m;
}
for (auto v : adj[u]) {
if (v == fa) continue;
dfs2(v, u);
}
}
void solve() {
int n;
cin >> n >> m;
for (int i = 1; i <= n - 1; i ++) {
int u, v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
dfs1(1, 0);
dp2[1] = 1;
dfs2(1, 0);
for (int i = 1; i <= n; i ++) {
cout << dp2[i] * dp[i] % m << "\n";
}
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
while (t-- ) {
solve();
}
return 0;
}
还没有评论,来说两句吧...