题目大意:
有一棵树,树上每个点都有一个球,每秒钟每个球都会向其父亲结点移动。除了跟结点之外,其余每个结点有p的概率为存储点,当球移到存储点则该球从树中删除。另外同一秒钟一个点上不能有一个球以上,即使是存储点也一样,如果出现则整棵树不合法
解题思路:
- 首先能够知道的是,如果整颗树是合法的,那么每个结点的子结点最多只有一个不是存储点
- 那么设置 s c o r e [ u ] score[u] score[u]为当前结点能够得到的分数,则状态转移为: s c o r e [ u ] = p q ∗ ∑ v u s o n ( s c o r e [ v ] + 1 ) score[u]=pq*\sum_{v}^{uson}(score[v]+1) score[u]=pq∗∑vuson(score[v]+1), p q pq pq为当前 v v v不为存储点其余点 v ′ v' v′为存储点的概率
- 但是!还需要考虑到存在不合法的情况导致无法继续,所以要先把合法的总概率得到,再看pq在合法总概率中的占比才行,即 p q = p q 合 法 总 概 率 pq=\frac{pq}{合法总概率} pq=合法总概率pq
- 除此之外,还需要计算每个子树合法的概率,最后用总答案乘整颗树合法的概率才为答案
反思:
- 做这道题的时候,笔者就是因为没有想到要在合法概率中考虑递推过程才导致始终无法算对,这个是一定要注意。此外最终要在这基础上考虑树的合法概率。
AC代码:
#include <bits/stdc++.h>
#define ft first
#define sd second
#define IOS ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define seteps(N) fixed << setprecision(N)
#define endl "\n"
const int maxn = 5e5 + 10;
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int, int> pii;
const ll mod = 998244353;
ll qpow(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> G[maxn];
int n;
ll p, prod[maxn], score[maxn];
void dfs(int u, int fu) {
ll cnt = 0;
for (auto v : G[u]) {
if (v == fu) continue;
dfs(v, u);
cnt++;
}
if (!cnt) {
prod[u] = 1; //无子节点,则合法概率就为1
return;
}
ll pq = qpow(p, cnt - 1) % mod * (mod + 1 - p) % mod;//子节点有一个不是存储点概率
ll pp = qpow(p, cnt);//子节点全是存储点概率
ll mm = (pp + cnt * pq % mod) % mod; //计算总合法概率
prod[u] = mm;
pq = pq * qpow(mm, mod - 2) % mod; //重新计算pq
for (auto v : G[u]) {
if (v == fu) continue;
prod[u] = prod[u] * prod[v] % mod;//计算当前子树的合法概率
score[u] = (score[u] + pq * (score[v] + 1) % mod) % mod;
//因为转移一步到u,贡献是score[v]再加上v结点的那1个球,所以是score[v]+1,因为当前score[v]是v的子树到v的贡献,并没有计算v结点的球
}
}
ll ans = 0;
int main() {
cin >> n >> p;
for (int i = 2, j; i <= n; i++)
cin >> j, G[i].push_back(j), G[j].push_back(i);
dfs(1, 0);
for (int i = 1; i <= n; i++)
ans = (ans + score[i]) % mod;
cout << ans * prod[1] % mod << endl; //最后乘上一整棵树合法概率
}
/*
5 332748118
1 2 2 3
4 332748118
1 1 2
6 332748118
1 1 3 3 4
*/