利用鞅停时定理、构造势能函数求解期望类问题

鞅、停时定理

鞅,用来描述一种 公平连续 随机过程。首先来看定义,这里只考虑离散意义下的鞅。

称随机过程 (X={X_n,nge 0}),若

  1. (E(|X_n|)<infty)
  2. (E(X_{n+1}|X_0,cdots,X_n)=E(X_n))

称随机过程 (Y={Y_n,nge 0}) 是关于 (X),若

  1. (Y_n) 仅仅与 (X_0cdots X_n) 有关;
  2. (E(Y_{n+1}|X_0,cdots,X_n)=E(Y_n))

直观来看,鞅就是一个随机过程:在已知前面所有 (s) 时刻之前的观测值,(s) 之后的期望与 (s) 时刻的期望相等。鞅描述了一种连续期望下的一种不动性。

随机时刻:设取值为 (Ncup{infty}) 的随机变量 (T),及随机过程 ({X_n,nge 0}),若 (forall nge 0),事件 ({T=n}) 的示性函数 (I_{{T=n}}) 仅仅是关于 (X_0,cdots,X_n) 的函数,则称 (T) 是随机过程 ({X_n,nge 0}) 的随机时刻。

停时:随机时刻 (T) 在不仅满足定义,并且满足 (P(T<infty)=1),则称 (T) 是随机过程 ({X_n,nge 0}) 的停时。

停止过程:若 (T) 是对过程 ({X_n,nge 0}) 的一个随机时刻,称 (X_{nland T}) 为停止过程,其中 (aland b=min{a,b})

不难证明停止过程也是关于 ({X_n,nge 0})

停时定理:假设 (M={M_n,nge 0}) 是关于 (X={X_n,nge 0}) 的鞅,(T) 是停时,(P(T<infty)=1),有 (E(M_{nland T})=E(M_0)).

若满足下列三个条件之一:

  1. (|M_{nland T}|) 几乎处处有界 (Leftrightarrow |M_{nland T}|le K);(( m bounded~in~space)
  2. (T) 几乎有限 (Leftrightarrow P(Tle K)=1);(( m bounded~in~time)
  3. (E(T)<infty),并且 (E(|M_{n+1}-M_n|mid X_0cdots X_n)le K);(( m bounded~in~increments)

则有 (E(M_T)=E(M_0)) 成立。

猴子打字问题

给定字符集大小为 (m),长度为 (n) 的串 (s)。初始时,令字符串 (t=phi),每次在 (t) 后面随机加入一个字符。求 (s) 第一次成为 (t) 后缀的期望时间。

常规做法:设 (F(x)) 表示不同长度下,(s) 第一次成为 (t) 后缀的概率生成函数,(G(x)) 表示不同长度下,(s) 没有成为 (t) 后缀的概率生成函数。

(G) 后加任意一个字符,只会变成 (F)(G) 的一种,得到

[xG(x)+1=F(x)+G(x)Rightarrow G(x)=frac{1-F(x)}{1-x} ]

(G) 后面添加 (s),有可能提前成为 (F),成为 (F) 之前加入的部分一定为 ( m border)。设 (c(x)=sum_{i=1}^n[s[1,i]=s[n-i+1,n]](frac xm)^{n-i}),得到

[F(x)c(x)=G(x)left(frac xm ight)^n ]

联立得到

[F(x)(x^n+m^nc(x)(1-x))=x^n ]

期望为 (F'(1))。两边求导后代入 (F(1)=1)(x=1),即可得到结果为 (sum_{i=1}^n[s[1,i]=s[n-i+1,n]]m^i)

使用 停时定理 也可求解。

假设在每个时刻,有一个赌徒拿着 1 元钱入场,并押当前这一次随机的字符为 (s_1)。如果没押中,输光离场;押中了,资金变成 (m) 倍。下一次他押 (s_2),同样按照刚刚的方法;下一次押 (s_3)(s_4)(cdots),直到押中 (s_n) 为止,此时他有 (m^n) 元钱,或者输光离场。

不难发现每个赌徒在任何时候的 期望收益 为 0,在第 (t) 个时刻后,设所有赌徒的 金额总和 期望为 (A_t),则 ({A_t-t,tge 0}) 是鞅。

(T=min{x:t[n-x+1,n]=s}),则 (T) 是一个停时,同时 (0le A_{tland T}-tland Tle sum_{i=1}^nm^i-n) 有界,由停时定理得到

[E(A_T-T)=E(A_0-0) ]

[E(A_0-0)=E(A_0)=0 ]

[E(T)=E(A_T)=sum_{i=1}^n[s[1,i]=s[n-i+1,n]]m^i ]

(E(A_T)) 的意义为:(T) 到来时(即结束时),所有赌徒的金额总和。显然上式成立。

势能函数

我们发现求解这类问题的关键,就是选取一个好的鞅,利用停时定理求解方程。这时,构造一个好的 势能函数 将会大有功用。

给定随机序列 (A={A_n,nge 0})(T) 为停时,求 (E(T))

构造势能函数 (Phi(A)),满足:

  1. (E(Phi(A_{n+1})-Phi(A_n)|A_0,cdots,A_n)=-1)
  2. (Phi(A_T)) 为常数,且 (Phi(A_i)=Phi(A_T)) 当且仅当 (i=T)

构造序列 (X_n=Phi(A_n)+n),则 (X={X_n,nge 0}) 是关于 (A) 的鞅。

利用停时定理,得到:(E(X_T)=E(X_0)),即 (E(Phi(A_T)+T)=E(Phi(A_0))Rightarrow E(T)=E(Phi(A_0))-Phi(A_T))

CF1025G Company Acquisitions

给定 (n) 个节点,每个节点要么为根,要么父亲为根;

现在有一种操作:等概率选取两个 不同的根 (x)(y)(关心顺序),将 (y) 的所有孩子变成根(有可能没有),(y) 的父亲设成 (x)

该操作当且仅当只剩下一个根时结束。

询问期望操作数,对 (10^9+7) 取模。(n le 500)

做法:设一棵有 (x) 个孩子的树的势能为 (f(x)),当前局面势能 (Phi(A)=sum_{a_iin A}f(a_i))。对于操作,假设两棵树的孩子分别为 (x)(y),操作完成以后,对于先后状态的变化关系,根据 (x ightarrow y)(y ightarrow x) 的概率各占一半,利用上面的公式,我们可以列出

[Phi(A_{n+1})-Phi(A_n)=-1Rightarrowleft(frac12(f(x+1)+yf(0))+frac12(f(y+1)+xf(0)) ight)-(f(x)+f(y))=-1 ]

由于是势能,我们不关心 (f(0)) 的值,不妨设 (f(0)=0),得到

[f(x)+f(y)=frac12f(x+1)+frac12f(y+1)+1 ]

[Rightarrow f(x+1)+f(y+1)=(2f(x)-1)+(2f(y)-1) ]

由于对于任意 (x,y) 方程均成立,我们可以写出

[f(x+1)=2f(x)-1 ]

解得 (f(x)=1-2^x)

依据停时定理,最后求起末状态的势能差即可。

CF850F Rainbow Balls

袋子里有 (n) 种颜色的球,第 (i) 种颜色有 (a_i) 个。

每次操作:等概率取出两个球 (x)(y)(有序),将 (y) 的颜色变成 (x) 的颜色。操作直到所有球颜色相同时停止。

期望多少次操作后停止。答案对 (10^9+7) 取模。

(nle 2500)(a_ile 10^5)

常规做法:设 (f_i) 表示当下某种颜色的球有 (i) 个,该颜色能成为成为最终所有球的颜色时的期望次数。首先 (f_i) 是条件期望,由全期望公式,答案就是

[sum_{i=1}^np_{a_i}f_{a_i} ]

(p_{a_i}) 表示某种颜色有 (a_i) 个,其能成为最终颜色的概率。

第一步,我们要求解 (p_i)。假设 (s=sum_{i=1}^na_i),不难列出

[p_i=frac{i(s-i)}{s(s-1)}(p_{i-1}+p_{i+1})+left(1-frac{2i(s-i)}{s(s-1)} ight)p_i Rightarrow 2p_i=p_{i-1}+p_{i+1} ]

易知 ({p}) 成等差,代入 (p_0=0)(p_s=1) 得到 (p_i=frac is)

现在列期望的方程。由条件期望得到

[f_i=frac{p_{i-1}}{p_i}frac{i(s-i)}{s(s-1)}f_{i-1}+frac{p_{i+1}}{p_i}frac{i(s-i)}{s(s-1)}f_{i+1}+left(1-frac{p_{i-1}}{p_i}frac{i(s-i)}{s(s-1)}-frac{p_{i+1}}{p_i}frac{i(s-i)}{s(s-1)} ight)f_i+1 ]

[Rightarrow 2if_i=(i-1)f_{i-1}+(i+1)f_{i+1}+frac{s(s-1)}{s-i} ]

(g_i=if_i-(i-1)f_{i-1}),有 (g_{i+1}=g_i-frac{s(s-1)}{s-i}) 成立,再令 (h_i=g_{i+1}-g_{i}=-frac{s(s-1)}{s-i}),则 (g_n=g_1+sum_{i=1}^{n-1}h_i)(nf_n=sum_{i=1}^ng_i=ng_1+sum_{i=1}^{n-1}(n-i)h_i),代入 (f_s=0) 得到

[sg_1=sf_1=s(s-1)^2Rightarrow f_1=(s-1)^2 ]

剩余部分线性递推即可。复杂度 (mathcal O(max a_ilog P))

势能法:定义 (f(x)) 表示同种颜色有 (x) 个球的势能,当前局面势能 (Phi(A)=sum_{a_iin A}f(a_i))。对于操作:我们有 (frac{a_i(a_i-1)}{s(s-1)}) 的概率选出来两个相同颜色的球,有 (frac{a_ia_j}{s(s-1)}) 的概率将 (i) 变成 (j)

于是有

[Phi(A_{n+1})=frac1{s(s-1)}left(sum_ia_i(a_i-1)Phi(A_n)+sum_{i e j}a_ia_j(Phi(A_n)-f(a_i)-f(a_j)+f(a_i+1)+f(a_j-1)) ight) ]

[Rightarrow Phi(A_{n+1})-Phi(A_n)=sum_{i e j}frac{a_ia_j}{s(s-1)}(f(a_i+1)+f(a_j-1)-f(a_i)-f(a_j)) ]

[Rightarrow Phi(A_{n+1})-Phi(A_n)=sum_{i e j}frac{a_ia_j}{s(s-1)}(f(a_i+1)+f(a_i-1)-2f(a_i))=-1 ]

最后一步利用 ((i,j))((j,i)) 对调部分项得到。

继续

[sum_ifrac{a_i(s-a_i)}{s(s-1)}(f(a_i+1)+f(a_i-1)-2f(a_i))=-1 ]

[Rightarrowsum_ia_ileft(1+frac{s-a_i}{s-1}(f(a_i+1)+f(a_i-1)-2f(a_i)) ight)=0 ]

我们希望这个式子恒成立,于是直接令

[1+frac{s-a_i}{s-1}(f(a_i+1)+f(a_i-1)-2f(a_i))=0 ]

[(f(x+1)-f(x))-(f(x)-f(x-1))=-frac{s-1}{s-x} ]

似曾相识?!基本上跟上面一样了。

CF1349D Slime and Biscuits

(n) 个人,第 (i) 个人拥有 (a_i) 块饼干。

每次操作,等概率随机一块饼干,假设这是 (x) 的饼干,再等概率随机除 (x) 外的一个人 (y),将 (x) 的这块饼干交给 (y)。该过程直到一个人拥有所有饼干。

求期望操作次数。(nle 10^5)(sum a_ile3 imes10^5)

常规做法:(咕咕咕)

势能法:令 (S=sum a_i),设 (f(x)) 表示某个人有 (x) 块饼干时的势能,当前局面总势能 (Phi(A))(sum_{a_iin A}f(a_i))。老生常谈,写出

[Phi(A_{n+1})-Phi(A_n)=sum_ifrac{a_i}Sleft(sum_{j e i}frac1{n-1}(f(a_j+1)+f(a_i-1)-f(a_j)-f(a_i)) ight)=-1 ]

[Rightarrowsum_ifrac{a_i}Sleft(1+sum_{j e i}frac1{n-1}(f(a_j+1)+f(a_i-1)-f(a_j)-f(a_i)) ight)=0 ]

[Rightarrowsum_ifrac1{S(n-1)}left(a_i(n-1)-a_i(n-1)(f(a_i)-f(a_i-1))+(S-a_i)(f(a_i+1)-f(a_i)) ight)=0 ]

方便地,我们令

[a_i(n-1)-a_i(n-1)(f(a_i)-f(a_i-1))+(S-a_i)(f(a_i+1)-f(a_i))=0 ]

[Rightarrow f(x+1)=frac{S+x(n-2)}{S-x}f(x)-frac{(n-1)x}{S-x}f(x-1)-frac{(n-1)x}{S-x} ]

(f(0)=0),代入 (x=0),解得 (f(1)=0)。于是可以快乐地线性递推。

最后求势能差即可。

自己在一道题目上的尝试

(树上移动):给定一棵 (n) 个节点的树,(i) 号节点的父亲为 (f_i(f_i<i))。每个节点的颜色要么为黑,要么为白。起始时,等概率随机一个节点作为起点。之后每一次,从 (n) 个点中等概率选取一个节点 (x),从当前点走到 (x),并且翻转节点 (x) 的颜色(黑->白 或者 白->黑)。该过程直到所有节点都变成白色或者黑色时停止。求期望走过的路径长度和,答案对 (10^9+7) 取模。

(nle 10^5)

这道题是我自己想出来利用 停时定理,构造一个合适的鞅来求解,希望能够起到抛砖引玉之效。

首先该问题与之前的问题不太一样:之前要求解期望时间,而这里要求解期望路径长度。势能法不能直接运用于此。

首先我们来描述这个随机游走的过程。

(X_n) 表示第 (n) 个时刻下关于点的随机变量,其中每个点等概率;(E[Y_n]) 表示第 (n) 个时刻,期望走过的路径长度和。根据定义有 (E[Y_n]=E[sum_{i=1}^n{ m dis}(X_{i-1}, X_i)])

令停时 (T) 表示所有节点第一次全部变成白/黑的时刻,该随机时刻描述了何时过程结束。我们的问题就是要求解 (E[Y_T]) 的值。

(overline d=frac{sum_{x,y}{ m dis}(x,y)}{n^2}),显然 (E[{ m dis}(X,X)]=overline d)。令 (overline{d_x}=frac{sum_y{ m dis}(x,y)}n),显然 (E[{ m dis}(x,X)]=overline{d_x})

为了构成鞅,我们考虑令 (Z_n=Y_n-noverline d)。但遗憾的是,根据鞅的定义,(E[Z_{n+1}|X_0,cdots,X_n]) 可能不等于 (E[Z_n|X_0,cdots,X_n]),也就是说 (Z) 不是鞅!最主要的原因:(E[Z_{n+1}|X_0,cdots,X_n])(X_n) 相关!(Y) 的增量可能小于(或大于)(overline d),比如 (E[{ m dis}(x, X)]<E[{ m dis}(X,X)]),这些增量无法通过后面减法的部分配平。

仔细思考发现 (E[Y_{n+1}|X_0,cdots,X_n]) 仅仅与 (X_n) 相关!即 (E[Y_{n+1}|X_0,cdots,X_n]=E[Y_{n+1}|X_n])。我们来尝试构造函数 (f(X)) 来辅助配平式子,也就是让

[E[Y_{n+1}+f(X_{n+1})-(n+1)overline dmid X_n]=Y_n+f(X_n)-noverline d ]

成立。

于是我们尝试列方程。由于 (X_n) 已知,假设 (X_n=x),能得到

[Y_n+f(x)-noverline d=frac1nsum_yY_{n+1}+f(y)-(n+1)overline d ]

[Rightarrow Y_{n+1}-Y_n=f(x)-frac1nleft(sum_yf(y) ight)+overline d=E[{ m dis}(x,X_{n})]=overline{d_x} ]

该式对于任意 (x) 均成立。直接令 (f(x)=overline{d_x}-overline d) 即可。

这样,令 (Z_n=Y_n+f(X_n)-noverline d)(Z) 将关于 (X) 构成鞅。不难得出 (E(T<infty)=1),并且根据构造,(E[|Z_{n+1}-Z_n|]) 显然有界,于是乎可以利用 停时定理 了!

[E[Z_T]=E[Z_0]=E[f(X_0)] ]

[Rightarrow E[Y_T+f(X_T)-Toverline d]=E[f(X_0)] ]

[Rightarrow E[Y_T]=overline dE[T]-E[f(X_T)]+E[f(X_0)] ]

其中

[E[f(X_T)]=sum_xf(x){ m Pr}(X_T=x) ]

({ m Pr}(X_T=x)) 的意义是:最后一次翻转的点为 (x) 的概率。(E[T]) 表示期望操作次数。两者直接列 DP 求解即可。

回顾刚刚的过程,我们发现:鞅和停时定理的运用,可以帮助我们转化问题、简化问题,避免某些复杂的状态设计,甚至有可能在消元上都要折磨大家(本题的一种常规做法在消元上较为麻烦)。求解问题的关键,就是选取一个合适的鞅,有时为了构造鞅,甚至需要构造合适的函数,结合停时赋予的实际意义,这样转化会变得十分方便。

#include <bits/stdc++.h>
typedef long long ll;
const int N = 1e5 + 5, P = 1e9 + 7;
int n, fa[N], siz[N], dis[N], dep[N], sdep, inv[N], cnt;
char s[N];
void upd(int &a, ll b) { (a += b) %= P; }
int qpow(int a, int b) {
	int c = 1;
	for (; b; b >>= 1, a = (ll)a * a % P)
		if (b & 1) c = (ll)c * a % P;
	return c;
}
struct Data {
	int x, y;
	Data(int x = 0, int y = 0) : x(x), y(y) {}
	Data operator + (Data o) { return Data((x + o.x) % P, (y + o.y) % P); }
	Data operator - (Data o) { return Data((x - o.x + P) % P, (y - o.y + P) % P); }
	Data friend operator * (Data o, ll k) { return Data(k * o.x % P, k * o.y % P); }
	int v(int o) { return ((ll)x * o + y) % P; }
} f[N], g[N];
int main() {
	scanf("%d%s", &n, s + 1);
	for (int i = 1; i <= n; i++)
		siz[i] = 1, cnt += s[i] == '1';
	inv[1] = 1;
	for (int i = 2; i <= n; i++)
		scanf("%d", &fa[i]), inv[i] = (ll)(P - P / i) * inv[P % i] % P;
	for (int i = n; i > 1; i--) upd(siz[fa[i]], siz[i]);
	for (int i = 1; i <= n; i++)
		dis[i] = (dis[fa[i]] - siz[i] + P) % P, upd(sdep, dep[i] = dep[fa[i]] + 1);
	for (int i = 1; i <= n; i++)
		upd(dis[0], dis[i] = (dis[i] * 2 + (ll)n * dep[i] + sdep) % P * inv[n] % P);
	dis[0] = (ll)dis[0] * inv[n] % P;
	f[1] = g[1] = {1, 0};
	for (int i = 1; i < n; i++)
		f[i + 1] = ((f[i] * n * inv[i] - f[i - 1]) * (i + 1) - Data(0, inv[i])) * inv[n - i - 1],
		g[i + 1] = (g[i] * n - g[i - 1] * i - Data(0, n)) * inv[n - i];
	int x = (ll)(P + 1 - f[n - 1].y) * qpow(f[n - 1].x + n - 1, P - 2) % P, y = (ll)(P - g[n].y) * qpow(g[n].x, P - 2) % P;
	int ans = (ll)dis[0] * g[cnt].v(y) % P;
	for (int i = 1; i <= n; i++)
		ans = (ans - (ll)(dis[i] - dis[0]) * (f[s[i] == '0' ? cnt : n - cnt].v(x) - inv[n]) % P + P) % P;
	printf("%d
", ans);
	return 0;
}
原文地址:https://www.cnblogs.com/ac-evil/p/14823488.html