???+ note "问题"
给定一张 $n$ 个结点、 $m$ 条边的简单无向图,用 RGB 三种颜色给每个结点染色 满足任意一对邻居都不同色,或者报告无解。
-???+ note "解法"
- 对每个点 $v$ ,从 $\{R,G,B\}$ 中等概率独立随机地选一种颜色 $C_v$ ,并钦定 $v$ **不** 被染成 $C_v$ 。最优解恰好符合这些限制的概率,显然是 $\big(\frac 23\big)^n$ 。
+对每个点 $v$ ,从 $\{R,G,B\}$ 中等概率独立随机地选一种颜色 $C_v$ ,并钦定 $v$ **不** 被染成 $C_v$ 。最优解恰好符合这些限制的概率,显然是 $\big(\frac 23\big)^n$ 。
+
+在这些限制下,对于一对邻居 $(u,v)$ ,“ $u,v$ 不同色”的要求等价于以下这条“推出”关系:
- 在这些限制下,对于一对邻居 $(u,v)$ ,“ $u,v$ 不同色”的要求等价于以下这条“推出”关系:
+- 对于所有异于 $C_u,C_v$ 的颜色 $X$ ,若 $u$ 被染成 $X$ ,则 $v$ 被染成 $\{R,G,B\}\setminus\{X,C_v\}$ 。
- - 对于所有异于 $C_u,C_v$ 的颜色 $X$ ,若 $u$ 被染成 $X$ ,则 $v$ 被染成 $\{R,G,B\}\setminus\{X,C_v\}$ 。
+于是我们可以对每个 $v$ 设置布尔变量 $B_v$ ,其取值表示 $v$ 被染成两种剩余的颜色中的哪一种。借助 2-SAT 模型即可以 $O(n+m)$ 的复杂度解决这个问题。
- 于是我们可以对每个 $v$ 设置布尔变量 $B_v$ ,其取值表示 $v$ 被染成两种剩余的颜色中的哪一种。借助 2-SAT 模型即可以 $O(m)$ 的复杂度解决这个问题。
+这样做,单次的正确率是 $\big(\frac 23\big)^n$ 。将算法重复运行 $-\big(\frac 32\big)^n\log \epsilon$ 次,只要有一次得到解就输出,这样即可保证 $1-\epsilon$ 的正确率。(详见后文中“自然常数的使用”和“抽奖问题”)
- 这样做,单次的正确率是 $\big(\frac 23\big)^n$ 。将算法重复运行 $-\big(\frac 32\big)^n\log \epsilon$ 次,只要有一次得到解就输出,这样即可保证 $1-\epsilon$ 的正确率。(详见后文中“自然常数的使用”和“抽奖问题”)
+---
**回顾** :本题中“解空间”就是集合 $\{R,G,B\}^n$ ,我们每次通过随机施加限制来在一个缩小的范围内搜寻“目标解”——即合法的染色方案。
### 例: [CodeChef SELEDGE](https://www.codechef.com/problems/SELEDGE)
+???+ note "简要题意"
+ to be written
+
观察:如果选出的边中有三条边构成一条链,则删掉中间的那条一定不劣;如果选出的边中有若干条构成环,则删掉任何一条一定不劣。
推论:最优解选出的边集,一定构成若干个不相交的菊花图(即直径不超过 2 的树)。
### 例: [Gym 101550I](https://codeforces.com/gym/101550/attachments)
+???+ note "简要题意"
+ to be written
+
整张图可以拆分为一个环加上四条从环伸出去的链。对于这四条链中的任何一条(记作 $C$ ),考虑在这条链上如何放置窃听器,容易通过贪心算法得到满足以下条件的方案:
- 在拦截所有 $C$ 内部进行的通话的前提下,用的窃听器数量最少。
### 例: [CSES 1685 New Flight Routes](https://cses.fi/problemset/task/1685)
+???+ note "简要题意"
+ to be written
+
先对原图进行强连通缩点。我们的目标显然是使每个汇点能到达每个源点。
不难证明,我们一定只会从汇点到源点连边,因为任何其他的连边,都能对应上一条不弱于它的、从汇点到源点的连边。
复杂度 $O\big((|V|+|E|) \log |V|\big)$ 。
+---
+
**回顾** :我们需要确定任意一对能够实现目标 I 的二元组 $(s,t)$ ,为此我们随机选择 $(s,t)$ 。
## 用随机化获得随机数据的性质
+如果一道题的数据随机生成,我们可能可以利用随机数据的性质解决它。而在有些情况下,即使数据并非随机生成,我们也可以通过随机化来给其赋予随机数据的某些特性,从而帮助解决问题。
+
### 例:随机增量法
随机生成的元素序列可能具有“前缀最优解变化次数期望下很小”等性质,而随机增量法就通过随机打乱输入的序列来获得这些性质。
### 例: [TopCoder MagicMolecule](https://community.topcoder.com/stat?c=problem_statement&pm=11705) 随机化解法
+???+ note "简要题意"
+ to be written
+
不难想到折半搜索。把点集均匀分成左右两半 $V_L,V_R$ (大小都为 $\dfrac n2$ ),计算数组 $f_{L,k}$ 表示点集 $L\subseteq V_L$ 中的所有 $\geq k$ 元团的最大权值和。接着我们枚举右半边的每个团 $C_R$ ,算出左半边有哪些点与 $C_R$ 中的所有点相连(这个点集记作 $N_L$ ),并用 $f_{N_L,\frac 23 n-|C_R|}+\textit{value}(C_R)$ 更新答案。
- 注意到可以 $O(1)$ 转移每一个 $f_{L,k}$ 。具体地说,取 $d$ 为 $L$ 中的任意一个元素,然后分类讨论:
- 解决方案:在 $V_L,V_R$ 内部再次折半;当查询一个子集的权值和时,将这个子集分成左右两半查询,再把答案相加。
- 这样即可通过本题。
- **回顾** :一个随机的集合有着“在划分出的两半的数量差距不会太悬殊”这一性质,而我们通过随机划分获取了这个性质。
+---
+
+ **回顾** :一个随机的集合有着“在划分出的两半的数量差距不会太悬殊”这一性质,而我们通过随机划分获取了这个性质。
## 随机化用于哈希
### 例: [UOJ #207 共价大爷游长沙](https://uoj.ac/problem/207)
+???+ note "简要题意"
+ to be written
+
对图中的每条边 $e$ ,我们定义集合 $S_e$ 表示经过该边的关键路径(即题中的 $(a,b)$ )集合。考虑对每条边动态维护集合 $S_e$ 的哈希值,这样就能轻松判定 $S_e$ 是否等于全集(即 $e$ 是否是“必经之路”)。
哈希的方式是,对每个 $(a,b)$ 赋予 $2^{64}$ 以内的随机非负整数 $H_{(a,b)}$ ,然后一个集合的哈希值就是其中元素的 $H$ 值的异或和。
2. 用 BM 算法求出该递推式。
3. 借助递推式,用凯莱哈密顿定理计算出 $S(N)$ 。
-这里仅关注第二部分,即如何求一个矩阵序列的递推式。
+这里仅关注第二部分,即如何求一个矩阵序列的递推式。所以我们只需考虑下述问题:
+
+???+ note "问题"
+ 给定一个矩阵序列,该序列在模 $P=998244353$ 意义下服从一个齐次线性递推式(递推式中的数乘和加法运算定义为矩阵的数乘和加法),求出最短递推式。
如果一系列矩阵服从一个递推式 $F$ ,那么它的每一位也一定服从 $F$ 。然而,如果对某一位求出最短递推式 $F'$ ,则 $F'$ 可能会比 $F$ 更短,从而产生问题。
-解决方案是,给矩阵的每一位 $(i,j)$ 赋予一个 $< P=998244353$ 的随机权值 $x_{i,j}$ ,计算序列中每个矩阵的所有位的加权和模 $P$ 的结果,然后对所得数列运行 BM 算法。
+解决方案是,给矩阵的每一位 $(i,j)$ 赋予一个 $<P$ 的随机权值 $x_{i,j}$ ,计算序列中每个矩阵的所有位的加权和模 $P$ 的结果,然后对所得数列运行 BM 算法。
错误率分析:
### 例: [UOJ #552 同构判定鸭](https://uoj.ac/problem/552) 及其错误率分析
+???+ note "简要题意"
+ to be written
+
令 $f_{K,i,j}$ 表示图 $G_K$ 中从点 $i$ 开始的所有长为 $j$ 的路径,这些路径对应的所有字符串构成的多重集的哈希值。按照 $j$ 升序考虑每个状态,转移时枚举 $i$ 的出边并钦定该边为路径上的第一条边。
-要判断是否存在长度 $=L$ 的坏串,只需把 $f_{0,*,L}$ 和 $f_{1,*,L}$ 分别“合并”起来再比较即可(通配符 `*` 这里表示每一个结点)。官方题解[^ref2]中证明了最短坏串(如果存在的话)长度一定不超过 $n_1+n_2$ ,所以这个解法的复杂度是可靠的。
+要判断是否存在长度 $=L$ 的坏串,只需把 $\{f_{0,*,L}\}$ 和 $\{f_{1,*,L}\}$ 各自“整合”起来再比较即可(通配符 `*` 这里表示每一个结点,例如 $\{f_{0,*,L}\}$ 表示全体 $f_{0,i,L}$ 构成的集合,其中 $i$ 取遍所有结点)。官方题解[^ref2]中证明了最短坏串(如果存在的话)长度一定不超过 $n_1+n_2$ ,所以这个解法的复杂度是可靠的。
-接下来考虑具体的哈希方式。注意到常规的哈希方法——即把串 $a_1a_2\cdots a_k$ 映射到 $\big(a_1+Pa_2+P^2a_3+\cdots+P^{k-1}a_k\big)\bmod Q$ 上、再把多重集的哈希值定为其中元素的哈希值之和模 $Q$ ——在这里是行不通的。一个反例是,集合 `{ab,cd}` 与集合 `{cb,ad}` 的哈希值是一样的,不论 $P,Q$ 如何取值。
+接下来考虑具体的哈希方式。注意到常规的哈希方法——即把串 $a_1a_2\cdots a_k$ 映射到 $\big(a_1+Pa_2+P^2a_3+\cdots+P^{k-1}a_k\big)\bmod Q$ 上、再把多重集的哈希值定为其中元素的哈希值之和模 $Q$ ——在这里是行不通的。一个反例是,集合 `{ab,cd}` 与集合 `{"cb","ad"}` 的哈希值是一样的,不论 $P,Q$ 如何取值。
上述做法的问题在于,一个串的哈希值是一个和式,从而其中的每一项可以拆出来并重组。为避免这一问题,我们考虑把哈希值改为一个连乘式。此外,乘法交换律会使得不同的位不可区分,为避免这一点我们要为不同的位赋予不同的权值。
推论:若 $x_1,\cdots,x_k$ 都在 $S$ 中等概率独立随机选取,则 $\mathrm{Pr}\big[f(x_1,\cdots,x_k)=0\big]\leq \dfrac d{|S|}$ 。
-记 $F$ 为模 $Q$ 的剩余系所对应的域,则对于一个 $L\leq n_1+n_2$ , $\sum\limits_i f_{0,i,L}$ 和 $\sum\limits_i f_{1,i,L}$ 就分别对应着一个 $F$ 上关于变元 $x_{*,*}$ 的 $L$ 次多元多项式,不妨将这两个多项式记为 $P_0,P_1$ 。
+记 $F$ 为模 $Q$ 的剩余系所对应的域,则对于一个 $L\leq n_1+n_2$ , $\sum\limits_i f_{0,i,L}$ 和 $\sum\limits_i f_{1,i,L}$ 就分别对应着一个 $F$ 上关于变元集合 $\{x_{*,*}\}$ 的 $L$ 次多元多项式,不妨将这两个多项式记为 $P_0,P_1$ 。
假如两个不同的字符串多重集的哈希值相同,则有两种可能:
1. $P_0\equiv P_1\pmod {Q}$ ,即 $P_0,P_1$ 的每一项系数在模 $Q$ 意义下都对应相等。
-2. $P_0\not\equiv P_1\pmod {Q}, P_0(x_{*,*})\equiv P_1(x_{*,*})\pmod {Q}$ ,即 $P_0,P_1$ 虽然不恒等,但我们选取的这一组 $x_{*,*}$ 恰好使得它们在此处的点值相等。
+2. $P_0\not\equiv P_1\pmod {Q}, P_0(x_{*,*})\equiv P_1(x_{*,*})\pmod {Q}$ ,即 $P_0,P_1$ 虽然不恒等,但我们选取的这一组 $\{x_{*,*}\}$ 恰好使得它们在此处的点值相等。
分析前者发生的概率:
$n\cdot m\leq 2\cdot10^5;q\leq 10^6;\epsilon=0.5,\delta=0.2$
-???+ note "解法"
- 引理:令 $X_{1\cdots k}$ 为互相独立的随机变量,且取值在 $[0,1]$ 中均匀分布,则 $\mathrm{E}\big[\min\limits_i X_i\big]=\dfrac 1{k+1}$ 。
+引理:令 $X_{1\cdots k}$ 为互相独立的随机变量,且取值在 $[0,1]$ 中均匀分布,则 $\mathrm{E}\big[\min\limits_i X_i\big]=\dfrac 1{k+1}$ 。
- - 证明:考虑一个单位圆,其上分布着 **相对位置** 均匀随机的 $k+1$ 个点,分别在位置 $0,X_1,X_2,\cdots,X_k$ 处。那么 $\min\limits_i X_i$ 就等于 $k+1$ 段空隙中特定的一段的长度。而因为这些空隙之间是“对称”的,所以其中任何一段特定空隙的期望长度都是 $\dfrac 1{k+1}$ 。
+- 证明:考虑一个单位圆,其上分布着 **相对位置** 均匀随机的 $k+1$ 个点,分别在位置 $0,X_1,X_2,\cdots,X_k$ 处。那么 $\min\limits_i X_i$ 就等于 $k+1$ 段空隙中特定的一段的长度。而因为这些空隙之间是“对称”的,所以其中任何一段特定空隙的期望长度都是 $\dfrac 1{k+1}$ 。
- 我们取 $k$ 为不同元素的个数,并借助上述引理来从 $\min\limits_i X_i$ 反推得到 $k$ 。
+我们取 $k$ 为不同元素的个数,并借助上述引理来从 $\min\limits_i X_i$ 反推得到 $k$ 。
- 考虑采用某个哈希函数,将矩阵中每个元素都均匀、独立地随机映射到 $[0,1]$ 中的实数上去,且相等的元素会映射到相等的实数。这样的话,一个子矩阵中的所有元素对应的那些实数,在去重后就恰好是先前的集合 $\{X_1,\cdots,X_k\}$ 的一个实例,其中 $k$ 等于子矩阵中不同元素的个数。
+考虑采用某个哈希函数,将矩阵中每个元素都均匀、独立地随机映射到 $[0,1]$ 中的实数上去,且相等的元素会映射到相等的实数。这样的话,一个子矩阵中的所有元素对应的那些实数,在去重后就恰好是先前的集合 $\{X_1,\cdots,X_k\}$ 的一个实例,其中 $k$ 等于子矩阵中不同元素的个数。
- 于是我们得到了算法:
+于是我们得到了算法:
- 1. 给矩阵中元素赋 $[0,1]$ 中的哈希值。为保证随机性,哈希函数可以直接用 `map` 和随机数生成器实现,即每遇到一个新的未出现过的值就给它随机一个哈希值。
- 2. 回答询问时设法求出子矩阵中哈希值的最小值 $M$ ,并输出 $\dfrac 1M-1$ 。
+1. 给矩阵中元素赋 $[0,1]$ 中的哈希值。为保证随机性,哈希函数可以直接用 `map` 和随机数生成器实现,即每遇到一个新的未出现过的值就给它随机一个哈希值。
+2. 回答询问时设法求出子矩阵中哈希值的最小值 $M$ ,并输出 $\dfrac 1M-1$ 。
- 然而,这个算法并不能令人满意。它的输出值的期望是 $\mathrm{E}\Big[\dfrac 1{\min\limits_i X_i}-1\Big]$ ,但事实上这个值并不等于 $\dfrac 1{\mathrm{E}\big[\min\limits_i X_i\big]}-1=k$ ,而(可以证明)等于 $\infty$ 。
+然而,这个算法并不能令人满意。它的输出值的期望是 $\mathrm{E}\Big[\dfrac 1{\min\limits_i X_i}-1\Big]$ ,但事实上这个值并不等于 $\dfrac 1{\mathrm{E}\big[\min\limits_i X_i\big]}-1=k$ ,而(可以证明)等于 $\infty$ 。
- 也就是说,我们不能直接把 $\min\limits_i X_i$ 的单次取值放在分母上,而要先算得它的期望,再把期望值放在分母上。
+也就是说,我们不能直接把 $\min\limits_i X_i$ 的单次取值放在分母上,而要先算得它的期望,再把期望值放在分母上。
- 怎么算期望值呢?多次随机取平均!
+怎么算期望值?多次随机取平均。
- 我们用 $C$ 组不同的哈希函数分别执行前述过程,回答询问时计算出 $C$ 个不同的 $M$ 值,并算出其平均数 $\overline M$ ,然后输出 $\big(\overline M\big)^{-1}-1$ 。
+我们用 $C$ 组不同的哈希函数分别执行前述过程,回答询问时计算出 $C$ 个不同的 $M$ 值,并算出其平均数 $\overline M$ ,然后输出 $\big(\overline M\big)^{-1}-1$ 。
- 实验发现取 $C\approx 80$ 即可满足要求。严格证明十分繁琐,在此略去。
+实验发现取 $C\approx 80$ 即可满足要求。严格证明十分繁琐,在此略去。
- 最后,怎么求子矩阵最小值?用二维 S-T 表即可,预处理 $O(nm\log n\log m)$ ,回答询问 $O(1)$ 。
+最后,怎么求子矩阵最小值?用二维 S-T 表即可,预处理 $O(nm\log n\log m)$ ,回答询问 $O(1)$ 。
## 随机化在算法中的其他应用
那么可以考虑使用随机堆,即不按照树高来交换儿子,而是随机交换。
-??? note "代码"
+???+ note "代码"
```cpp
struct Node {
int child[2];
- ……
- 随着层数越来越多,交替出现的上界和下界也越来越紧。这一系列结论形式上类似容斥原理,证明过程也和容斥类似,这里略去。
- **自然常数的使用** : $\Big(1-\dfrac 1n\Big)^n\leq \dfrac 1e,\forall n\geq1$
+---
+
+ **自然常数的使用** : $\Big(1-\dfrac 1n\Big)^n\leq \dfrac 1e,\forall n\geq1$
- 左式关于 $n\geq 1$ 单调递增且在 $+\infty$ 处的极限是 $\dfrac 1e$ ,因此有这个结论。
- 这告诉我们,如果 $n$ 个互相独立的坏事件,每个的发生概率为 $1-\dfrac 1n$ ,则它们全部发生的概率至多为 $\dfrac 1e$ 。
- **(\*) Hoeffding** 不等式:若 $X_{1\cdots n}$ 为互相独立的实随机变量且 $X_i\in [a_i,b_i]$ ,记随机变量 $X:=\sum\limits_{i=1}^n X_i$ ,则
+---
+
+ **(\*) Hoeffding** 不等式:若 $X_{1\cdots n}$ 为互相独立的实随机变量且 $X_i\in [a_i,b_i]$ ,记随机变量 $X:=\sum\limits_{i=1}^n X_i$ ,则
$$
\mathrm{Pr}\Big[\big|X-\mathrm{E}[X]\big|\geq t\Big]\leq2\exp {-\dfrac {t^2}{\sum\limits_{i=1}^n (b_i-a_i)^2}}
#### 例子
???+ note "例:抽奖问题"
- 一个箱子里有 $n$ 个球,其中恰有 $k$ 个球对应着大奖。你要进行若干次独立、等概率的随机抽取,每次抽完之后会把球放回箱子。请问抽多少次能保证以至少 $1-\epsilon$ 的概率,满足 **每一个** 奖球都被抽到至少一次?给出一个尽量紧的上界即可,不要求精确答案。
+ 一个箱子里有 $n$ 个球,其中恰有 $k$ 个球对应着大奖。你要进行若干次独立、等概率的随机抽取,每次抽完之后会把球放回箱子。请问抽多少次能保证以至少 $1-\epsilon$ 的概率,满足 **每一个** 奖球都被抽到至少一次?给出一个上界即可,不要求精确答案。
与该问题类似的模型经常出现在随机算法的复杂度分析中。
现在有 $k>1$ 个奖球,那么根据 Union Bound,我们只需保证每个奖球被漏掉的概率都不超过 $\dfrac \epsilon k$ 即可。于是答案是 $-n\log\dfrac \epsilon k$ 。
+---
+
???+ note "例:(\*)随机选取一半元素"
给出一个算法,从 $n$ 个元素中等概率随机选取一个大小为 $\dfrac n2$ 的子集,保证 $n$ 是偶数。你能使用的唯一的随机源是一枚均匀硬币,同时请你尽量减少抛硬币的次数(不要求最少)。
尝试用 Hoeffding 不等式求第二、第三步中操作次数期望值的上界:
$$
- E\Big[\big|X-E[X]\big|\Big]=\int\limits_0^\infty \mathrm{Pr}\Big[\big|X-\mathrm{E}[X]\big|\geq t\Big]\mathrm{d}t\leq2\int\limits_0^\infty \exp {-\dfrac {t^2}n}\mathrm{d}t=\sqrt{\pi n}
+ \mathrm{E}\Big[\big|X-\mathrm{E}[X]\big|\Big]=\int\limits_0^\infty \mathrm{Pr}\Big[\big|X-\mathrm{E}[X]\big|\geq t\Big]\mathrm{d}t\leq2\int\limits_0^\infty \exp {-\dfrac {t^2}n}\mathrm{d}t=\sqrt{\pi n}
$$
从而第二、第三步所需抛硬币次数的期望值是 $\sqrt{\pi n}\cdot2\lceil\log_2 n\rceil$ 。
#### 应用: [NERC 2019 Problem G: Game Relics](https://codeforces.com/contest/1267/problem/G)
+???+ note "简要题意"
+ to be written
+
观察:如果选择抽物品,就一定会一直抽直到获得新物品为止。
- 理由:如果抽一次没有获得新物品,则新的局面和抽物品之前的局面一模一样,所以如果旧局面的最优行动是“抽一发”,则新局面的最优行动一定也是“再抽一发”。
最后,我们枚举所有可能的局面(即已经拥有的元素集合),算出这种局面出现的概率(已有元素的排列方案数除以总方案数),乘上当前局面最优决策的代价(由拥有元素个数和剩余物品总价确定),再加起来即可。这个过程可以用背包式的 DP 优化,即可通过本题。
+---
+
**回顾** :可以看到,耦合的技巧在本题中使用了两次。第一次是在证明过程中,令两个随机过程使用同一个随机源;第二次是把购买转化成随机购买(即引入随机源),从而使得购买和抽取这两种操作实质上“耦合”为同一种操作(即令抽取和购买操作共享一个随机源)。
## 参考资料