关于此题CF2040E Control of Randomness 的一些总结[树形DP][概率DP]
题目大意:给定一棵树和q个询问,每个询问给定\(v,p\),表示一开始有p枚硬币,需要从顶点\(v\)走到顶点\(1\),假设当前走第\(i\)步,如果\(i\)是奇数,那么会朝着顶点\(1\)的方向走一步,如果是偶数,可以花费一枚硬币向顶点\(1\)方向走一步,否则会等概率地随机向任一当前节点所连顶点走一步,问从\(v\)走到\(1\)的期望步数。
思路:对于每个奇数步数很简单,而对于每个偶数步数的情况,我们需要推一下式子。假设当前要走的是第偶数步,并且当前所处节点的度是\(d\),根据期望计算公式,从当前节点向顶点\(1\)方向走的期望步数是
\(\displaystyle \lim_{m \to \infty }\sum_{k=1}^{m} \frac{1}{d}*\frac{d-1}{d}^{k-1}*(2k-1)\)
其中\((2k-1)\)表示走\((2k-1)\)步的情况。即,走\(1\)步的概率是\(\frac{1}{d}\),走\(2\)步的概率是\(\frac{1}{d}*\frac{d-1}{d}\)依次类推。
要求这个式子,我们先把它拆开:
\(\displaystyle \lim_{m \to \infty }(\sum_{k=1}^{m} \frac{1}{d}*\frac{d-1}{d}^{k-1}*2k - \sum_{k = 1}^{m}\frac{1}{d}*\frac{d-1}{d}^{k-1})\)
对于后半部分直接用等比数列求和公式即可求出是\(1\),而对于前半部分,由于
\(\sum_{k=0}^{\infty }r^{k}=\frac{1}{1-r}\)
我们对两边同时求导有
\(\sum_{k=0}^{\infty }kr^{k-1}=\frac{1}{(1-r)^{2}}\)
由于\(k\)为\(0\)时,即左式第一项为\(0\),所以可以直接令左式从\(1\)开始。所以我们直接将\(\frac{d-1}{d}\)带入求得\(d^{2}\),再乘上\(\frac{2}{d}\)得\(2d\),故上式结果为\(2d-1\)
代码:
#include<bits/stdc++.h>
using namespace std;
const long long mod = 998244353;
long long t;
const long long N = 2e5 + 10;
long long n,q,in[N],dep[N];
long long head[N],tot,ans,step;
bool flag;
struct node {
long long v,next;
}cnt[N];
priority_queue<long long> vt;
void insert(long long u,long long v) {
cnt[++tot].v = v;
cnt[tot].next = head[u];
head[u] = tot;
}
void dfs1(long long u,long long fa) {
dep[u] = dep[fa] + 1;
for(long long i = head[u];i;i = cnt[i].next) {
if(cnt[i].v == fa) continue;
dfs1(cnt[i].v,u);
}
}
void dfs2(long long u,long long fa,long long tg) {
if(u == tg) {
flag = true;
vt.push(1);
step++;
return;
}
for(long long i = head[u];i;i = cnt[i].next) {
if(cnt[i].v == fa) continue;
dfs2(cnt[i].v,u,tg);
if(flag == true) {
if(u != 1) {
step++;
if(step % 2 != 0) vt.push(1);
else vt.push((2 * in[u] - 1) % mod);
}
return;
}
}
}
void solve() {
for(long long i = 0;i <= n;i++) head[i] = dep[i] = in[i] = 0;
for(long long i = 0;i <= tot;i++) cnt[i].v = cnt[i].next = 0;
tot = 0;
cin >> n >> q;
for(long long u,v,i = 1;i < n;i++) {
cin >> u >> v;
insert(u,v);
insert(v,u);
in[u]++;
in[v]++;
}
dfs1(1,0);
for(long long v,p,i = 1;i <= q;i++) {
cin >> v >> p;
ans = flag = step = 0;
dfs2(1,0,v);
while(!vt.empty()) {
if(vt.top() > 1 && p > 0)
ans++,p--;
else ans += vt.top();
vt.pop();
ans %= mod;
}
cout << ans << '\n';
}
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin >> t;
while(t--) solve();
return 0;
}

浙公网安备 33010602011771号