Hall 定理
Hall 定理
引入
有 \(n\) 个男生,每个男生都有若干个喜欢的女生。
现在要求每个男生都与其中一个自己喜欢的女生牵手,且每个女生只能和一个男生牵手。
问是否存在一个方案。
定理:
当我们选择任意 \(k\ (k\in [1,n])\) 个男生,他们喜欢共有 \(\ge k\) 个不同的女生,那么就存在一个方案。
证明
我们考虑用归纳法证明:
-
当 \(n=1\) 时,显然成立。
-
当有 \(n\) 个男生,我们已经证明了 \(<n\) 时都是存在方案的,那么有:
-
如果任选 \(k(\not = n)\) 个男生,他们喜欢的都有 \(> k\) 个不同的女生,那么我们随便将一对男女配对,剩下的人依旧满足条件。
-
如果存在 \(k(\not = n)\) 个男生,他们喜欢恰好有 \(k\) 个不同的女生,那我们将这 \(k\) 对男女配对后去掉,剩下的人一定满足条件。(假如剩下的存在不满足条件的 \(p\) 个男生,那么我们将去掉的那 \(k\) 个男生加到其中,会发现喜欢的女生是 \(<k+p\) 人的,与原条件矛盾)
-
因此 Hall 定理成立。
相关引理
- 如果我们允许有 \(m\) 个男生找不到女朋友:
- 那么我们选择任意 \(k\ (k\in [1,n])\) 个男生,他们喜欢共有 \(\ge k-m\) 个不同的女生,那么就存在一个方案。
证明方法与上面的类似。
- 如果对于男生 \(i\),他打算牵手 \(a_i\) 个女生:
- 那么我们可以将这个男生看成 \(a_i\) 个人,每个个体都喜欢着原来 \(i\) 喜欢的女生,这样又回到原来的 Hall 定理了。
例题应用
我们考虑从 \(B\) 数列的角度出发。
我们设 \(S\) 是 \(B\) 的一个子集,\(N(S)\) 是 \(S\) 与 \(A\) 的相邻点构成的集合。
根据 Hall 定理,我们要成功匹配,必须有 \(|S|\le |N(S)|\)。
当我们将 \(B\) 从小到大进行排序,不难发现,对于一个 \(B\) 的两个前缀 \(P_1,P_2\ (|P_1|<|P_2|)\),有 \(N(P_1)\le N(P_2)\)。
因此,如果一个前缀 \(P\) 是满足 Hall 定理的,那么 \(B\) 中任选长度为 \(|P|\) 的子集一定也是满足条件的。
这样,我们只需要判断 \(B\) 的每个前缀是否满足条件即可。
这可以用线段树进行维护,具体的,我们需要保证 \(\min\{|N(P_i)|-i\}\ge 0\) 即可。
首先,我们需要二分答案。
对 \(A,B\) 进行排序,不难发现,对于 \(a_i\),它能匹配的应该是 \(B\) 上的连续一段(可能出现尾一段+头一段,我们将 \(B\) 复制一遍即可)
那么对于 \(a_i\) 和 \(a_j\)(\(i<j\)),假设他们在 \(B\) 上匹配的是 \([l_i,r_i]\) 及 \([l_j,r_j]\),那么根据 Hall 定理,一定要有 \(j-i\le r_j-l_i\)。
通过移项,得到 \(r_j-j \ge l_i-i\)。
根据这个条件,我们就可以用 \(O(n)\) 判断一个答案是否合法。