Solution - Atcoder ARC150D Removing Gacha

rizynvu發表於2024-07-08

考慮到每次操作都比定會選上一個點,於是答案可以表示為每個點被選中的次數之和。
即令 \(c_i\)\(i\) 點被選中的次數,答案即為 \(E(\sum\limits_{i = 1}^n c_i)\)

根據期望的線性性,考慮把答案的 \(E\) 拆到每個 \(c_i\) 上,即變為 \(\sum\limits_{i = 1}^n E(c_i)\) 的形式。

那麼對於每個點 \(i\) 就很好的獨立開了。
考慮到因為這個選取點是僅與其祖先有關的,所以可以考慮用深度 \(d = \operatorname{dep}_i\) 來表示其對應的期望次數。
即令 \(f_d\) 為深度為 \(d\)(一條長為 \(d\) 的鏈)的點期望被選取的次數,把答案轉為 \(\sum\limits_{i = 1}^{n} f_{\operatorname{dep}_i}\)

接下來考慮求解 \(f_d\)
因為這裡是均勻隨機的去做,所以對於包括其祖先的這 \(d\) 個點的被選中的期望次數應該是相同的。
所以考慮轉為總共期望多少次能夠把 \(d\) 個點都選中。
這個可以考慮已經選中了 \(i\) 個點,那麼下一次選中一個未被選中的點的機率就是 \(\frac{d - i}{d}\),對應的期望次數就是 \(\frac{d}{d - i}\)
所以總的期望次數就是 \(\sum\limits_{i = 0}^{d - 1} \frac{d}{d - i} = \sum\limits_{i = 1}^d \frac{d}{i} = d\times \sum\limits_{i = 1}^d \frac{1}{d}\)
所以有 \(f_d = \dfrac{d\times \sum\limits_{i = 1}^d \frac{1}{d}}{d} = \sum\limits_{i = 1}^d \frac{1}{d}\)

時間複雜度 \(\mathcal{O}(n)\)

#include<bits/stdc++.h>
using ll = long long;
constexpr ll mod = 998244353;
const int maxn = 2e5 + 10;
ll inv[maxn], f[maxn];
int fa[maxn], dep[maxn];
int main() {
   int n; scanf("%d", &n);
   dep[1] = 1;
   for (int i = 2; i <= n; i++) {
      scanf("%d", &fa[i]);
      dep[i] = dep[fa[i]] + 1;
   }
   inv[0] = inv[1] = 1ll;
   for (int i = 2; i <= n; i++)
      inv[i] = inv[mod % i] * (mod - mod / i) % mod;
   for (int i = 1; i <= n; i++)
      f[i] = (f[i - 1] + inv[i]) % mod;
   ll ans = 0;
   for (int i = 1; i <= n; i++)
      (ans += f[dep[i]]) %= mod;
   printf("%lld\n", ans);
   return 0;
}

相關文章