Loading

鞅与停时定理小记

赌博问题

\(X_i\) 为第 \(i\) 轮赌博后的收益。

根据常识,显然有 \(E(X_i)=X_0=0\)

离散时间鞅

定义一组离散时间鞅为时间离散的随机过程 \(\{X_0,X_1,X_2,...\}\),满足对于任意 \(n\),都有

  • \(|E(X_n)|<+\infty\),即取值是有限的。

  • \(E(X_{n+1}-X_n | X_0,X_1,...,X_n)=0\),意思是确定 \(X_0,X_1,...,X_n\) 后,\(X_{n+1}\) 的期望值等于 \(X_n\)

停时定理

停时:时间离散的随机过程的终止时刻。

\(T\) 为离散时间鞅 \(\{X_0,X_1,...\}\) 的停时。

当满足下面三个条件其中之一时,\(E(X_T)=X_0\) 成立:

  • \(T\) 有界。

  • \(E(|X_{i+1}-X_i|)\) 有界,\(E(T)\) 有限。

  • \(X_i\) 有界。

其中第二个条件是大部分题目都满足的。

势能函数

给出随机过程 \(\{X_0,X_1,X_2,...\}\) 的终止状态 \(X_T\),求 \(E(T)\)

构造势能函数 \(\varphi(X_i)\),满足:

  • \(E(\varphi(X_{n+1})-\varphi(X_n)=-1|X_0,X_1,...,X_n)=-1\)

  • \(E(\varphi(X_T))\) 为常数,且不存在 \(X'\not = X_T\) 满足 \(\varphi(X')=\varphi(X_T)\)

\(Y_i=\varphi(X_i)+i\),那么容易得到 \(Y\) 是一组离散时间鞅。根据停时定理,\(E(Y_T)=Y_0=\varphi(X_0)\)

\(E(\varphi(X_T)+T)=\varphi(X_0)\Leftrightarrow \varphi(X_T)+E(T)=\varphi(X_0)\Leftrightarrow E(T)=\varphi(X_0)-\varphi(X_T)\)

一般情况下,构造 \(\varphi(X)=\sum\limits_{i\in X} f(i)\)

例题

CF1025G Company Acquisitions

设接在点 \(u\) 的点个数为 \(c_u\),那么 \(\varphi(X)=\sum\limits_u f(c_u)\)

\(X\to X'\),我们需要满足 \(E(\varphi(X'))-E(\varphi(X))=-1\)

考虑一次改动选择了两个点 \(u,v\),设 \(x=c_u,y=c_v\),那么

\[f(x)+f(y)-1=\frac 12(f(x+1)+yf(0))+\frac 12(f(y+1)+xf(0)) \]

\(f(0)=0\)

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

\[f(x)=1-2^x \]

直接求即可。

点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define pir pair<ll,ll>
#define mkp make_pair
#define fi first
#define se second
#define pb push_back
using namespace std;
const ll maxn=510, mod=1e9+7;
ll n,a[maxn],c[maxn],pw[maxn],ans;
int main(){
	scanf("%lld",&n);
	pw[0]=1;
	for(ll i=1;i<=n;i++) pw[i]=pw[i-1]*2%mod;
	for(ll i=1;i<=n;i++){
		scanf("%lld",a+i);
		if(a[i]!=-1) ++c[a[i]];
	}
	for(ll i=1;i<=n;i++) ans=(ans+1+mod-pw[c[i]])%mod;
	ans=(ans+mod-(1-pw[n-1]))%mod;
	printf("%lld",ans);
	return 0;
}

CF1349D Slime and Biscuits

\(m\) 为总饼干数。

\(\varphi(X)=\sum\limits_{i=1}^n f(a_i)\)

那么 \(\sum\limits_{i=1}^n f(a_i)-1=\sum\limits_{i=1}^n (\dfrac {a_i}mf(a_i-1)+\dfrac{(n-2)(m-a_i)}{m(n-1)}f(a_i)+\dfrac{m-a_i}{m(n-1)}f(a_i+1)))\)。三部分分别表示送出饼干、饼干数不变、得到饼干。

考虑对于单个 \(a_i=x\),有

\[f(x)-\frac xm=\frac xmf(x-1)+\frac{(n-2)(m-x)}{m(n-1)}f(x)+\frac {m-x}{m(n-1)}f(x+1) \]

\[f(x+1)=\frac {m(n-1)}{m-x}(-\frac xmf(x-1)+(1-\frac{(n-2)(m-x)}{m(n-1)})f(x)-\frac xm) \]

\(f(0)=0\),当 \(x=0\) 时得到 \(f(1)=f(0)=0\),直接递推即可。

点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define pir pair<ll,ll>
#define mkp make_pair
#define fi first
#define se second
#define pb push_back
using namespace std;
const ll maxn=3e5+10, mod=998244353;
ll n,m,a[maxn],f[maxn],ans;
ll power(ll a,ll b=mod-2){
	ll s=1;
	while(b){
		if(b&1) s=s*a%mod;
		a=a*a%mod; b>>=1;
	} return s;
}
int main(){
	scanf("%lld",&n);
	for(ll i=1;i<=n;i++) scanf("%lld",a+i), m+=a[i];
	ll inv=power(m);
	for(ll i=1;i<m;i++)
		f[i+1]=m*(n-1)%mod*power(m-i)%mod*(mod-i*inv%mod*f[i-1]%mod+
		(mod+1-(n-2)*(m-i)%mod*power(m*(n-1)%mod)%mod)*f[i]%mod+mod-i*inv%mod)%mod;
	for(ll i=1;i<=n;i++) ans=(ans+f[a[i]])%mod;
	ans=(ans-f[m]+mod)%mod;
	printf("%lld",ans);
	return 0;
}

CF850F Rainbow Balls

\(\varphi(X)=\sum\limits_{i=1}^n f(a_i)\)

那么

\[f(x)-\frac xm = \frac {x(m-x)}{m(m-1)} (f(x-1)+f(x+1))+\frac{(m-x)(m-x-1)+x(x-1)}{m(m-1)}f(x) \]

\(t=\dfrac{x(m-x)}{m(m-1)}\),得

\[f(x)-\frac xm = t\cdot f(x-1)+t\cdot f(x+1)+(1-2t)f(x) \]

\[f(x+1)=\frac 1t (2t\cdot f(x)-t\cdot f(x-1)-\frac xm) \]

\[f(x+1)=2f(x)-f(x-1)-\frac{m-1}{m-x} \]

直接递推时间爆炸,考虑差分。

\(g(x)=f(x)-f(x-1)\),那么

\[g(x+1)=g(x)-\frac {m-1}{m-x} \]

\[g(x)=g(0)-\sum_{i=0}^{x-1} \frac{m-1}{m-i} \]

那么

\[\begin{aligned}f(x)&=f(0)+\sum_{i=1}^x g(i)\\ &= f(0)+xg(0)-\sum_{i=0}^{x-1} \frac{m-1}{m-i}\cdot (x-i) \\ &= f(0)+xg(0)-(m-1)\sum_{i=0}^{x-1} \frac{x-i}{m-i} \\ &= f(0)+xg(0)-(m-1)\sum_{i=0}^{x-1} (\frac{x-m}{m-i}+1) \\ &= f(0)+xg(0)+(m-1)(m-x)\sum_{i=0}^{x-1} \frac 1{m-i} -x(m-1) \end{aligned} \]

\(g(0)=m-1,f(0)=0\),得

\[f(x)=f(0)+(m-1)(m-x)\sum_{i=0}\frac 1{m-i} \]

\(x=m\) 时有 \(f(m)=0\),其他只需要递推到 \(10^5\) 即可。

点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define pir pair<ll,ll>
#define mkp make_pair
#define fi first
#define se second
#define pb push_back
using namespace std;
const ll maxn=3e5+10, mod=1e9+7;
ll n,m,a[maxn],f[maxn],ans;
ll power(ll a,ll b=mod-2){
	ll s=1;
	while(b){
		if(b&1) s=s*a%mod;
		a=a*a%mod; b>>=1;
	} return s;
}
int main(){
	scanf("%lld",&n);
	for(ll i=1;i<=n;i++) scanf("%lld",a+i), m+=a[i];
	for(ll i=1;i<=1e5;i++)
		f[i]=(f[i-1]+power(m-i+1))%mod;
	for(ll i=1;i<=1e5;i++)
		f[i]=f[i]*(m-1)%mod*(m-i)%mod;
	for(ll i=1;i<=n;i++) ans=(ans+f[a[i]])%mod;
	printf("%lld",ans);
	return 0;
}

CF1479E School Clubs

直接推式子。

\[f(x)-\frac xn=\frac{nx+x(n-x)}{2n^2}f(x-1)+\frac {x(n-x)}{2n^2}f(x+1) + (1-\frac{xn+2x(n-x)}{2n^2})f(x)-\frac{nx}{2n^2}f(1) \]

\[f(x)-\frac xn=\frac{2nx-x^2}{2n^2}f(x-1)+\frac {x(n-x)}{2n^2}f(x+1) + (1-\frac{3nx-2x^2}{2n^2})f(x)-\frac x{2n}f(1) \]

\[(n-x)f(x+1)=(3n-2x)f(x)-(2n-x)f(x-1)-2n-nf(1) \]

\(f(1)=-2\),得

\[(n-x)f(x+1)=(3n-2x)f(x)-(2n-x)f(x-1) \]

\[f(x+1)=\frac{(3n-2x)f(x)-(2n-x)f(x-1)}{n-x} \]

考虑对每个 \(f(x)\) 维护分子分母,即 \(f(x)=\dfrac{p(x)}{q(x)}\),分式乘除法即可。

点击查看代码
#include<bits/stdc++.h>
#define ll int
#define pir pair<ll,ll>
#define mkp make_pair
#define fi first
#define se second
#define pb push_back
using namespace std;
const ll maxn=3e5+10, mod=998244353;
ll n,m,a[maxn],p1,q1,p2,q2,ans;
ll power(ll a,ll b=mod-2){
	ll s=1;
	while(b){
		if(b&1) s=1ll*s*a%mod;
		a=1ll*a*a%mod; b>>=1;
	} return s;
}
int main(){
	scanf("%d",&m);
	for(ll i=1;i<=m;i++){
		scanf("%d",a+i);
		n+=a[i];
	}
	sort(a+1,a+1+m);
	p1=-2, p2=0;
	q1=q2=1;
	ll j=1;
	while(j<=m&&a[j]==1) ans-=2, ++j;
	for(ll i=1;i<n;i++){
		ll p=((long long)(3*n-(i<<1))*p1%mod*q2-(long long)((n<<1)-i)*p2%mod*q1)%mod, q=(long long)(n-i)*q1%mod*q2%mod;
		p2=p1, q2=q1;
		p1=p, q1=q;
		while(j<=m&&a[j]==i+1) ans=(ans+1ll*p*power(q))%mod, ++j;
	}
	ans=(ans-1ll*p1*power(q1))%mod;
	printf("%d",(ans+mod)%mod);
	return 0;
}
posted @ 2024-04-07 11:27  Sktn0089  阅读(19)  评论(0编辑  收藏  举报