UyHiP-2011-Nov

居然自己做出来了所以说还是很简单的 23333

Problem

定义布尔的乘运算为 AND ,加运算为 OR 。定义一个 DNF (析取范式)为一个布尔函数,返回值为若干个若干个变量的积的和,例如 f(x1,x2,x3)=x1x2+x2x3f(x_1, x_2, x_3) = x_1 x_2 + x_2 x_3 即为一 DNF 。注意这里定义的 DNF 没有 NOT 。

定义一个对称函数为:接受若干个布尔量,返回一个布尔量,且参数的顺序与返回值是无关的。例如 f(x1,x2)=x1x2f(x_1, x_2) = x_1 x_2 即为一对称函数。

我们说一个函数 A 能用另一个函数 B 表达,当且仅当存在一组参数列表之间的对应关系 y1=xa1,y2=xa2,,ym=xamy_1 = x_{a_1}, y_2 = x_{a_2}, \dots, y_m = x_{a_m} ,使得 A(x1,x2,,xn)=B(y1,y2,,ym)A(x_1, x_2, \dots, x_n) = B(y_1, y_2, \dots, y_m) 。例如函数 A(x1,x2,x3)A(x_1, x_2, x_3) 表示求 x1,x2,x3x_1, x_2, x_3 的众数,可以得到 A(x1,x2,x3)=x1x2+x2x3+x3x1A(x_1, x_2, x_3) = x_1 x_2 + x_2 x_3 + x_3 x_1 ,令 B(x1,x2,x3,x4,x5,x6)=x1x2+x3x4+x5x6B(x_1, x_2, x_3, x_4, x_5, x_6) = x_1 x_2 + x_3 x_4 + x_5 x_6 ,可以知道 A 能被 B 表达。

现在有两个问题:

  1. 对于所有的 DNF ,都可以找到一个对称函数使得其能表达这个 DNF ?
  2. 对于所有的对称函数,都可以找到一个 DNF 使得其能表达这个对称函数?

题目似乎很绕……→_→

Solution

考虑任意一个对称函数,由于参数顺序是无关的,所以对于这个对称函数我们只关心它的参数中有多少个 1 有多少个 0 。换而言之,一个对称函数 A 等价于一个二元函数 f(a,b)f(a, b) ,其中 aa 表示参数中 1 的个数, bb 表示参数 0 的个数。

再考虑一个 DNF 。可以发现 DNF 的值不会随变量的递增而递减,也就是说对于两组参数 x1,x2,,xnx_1, x_2, \dots, x_ny1,y2,,yny_1, y_2, \dots, y_n ,如果满足 f(x1,x2,,xn)=1f(x_1, x_2, \dots, x_n) = 1x1y1,x2y2,,xnynx_1 \leq y_1, x_2 \leq y_2, \dots, x_n \leq y_n ,则一定有 f(y1,y2,,yn=1f(y_1, y_2, \dots, y_n = 1

所以 DNF 能表达的函数就少得多,考虑一个简单的对称函数 f(x)f(x) 表示 NOT x ,可以发现 ff 是递减的,用 DNF 就表达不出来。所以问题二是错的,上面说的 ff 就是个反例。

而对于任意一个 DNF ,所有不同的参数列表是有限的。假设一个 DNF 有 nn 个参数,则有 2n2^n 中不同的参数列表。考虑一个二元非布尔函数 f(a,b)f(a, b) 保证 a+b=2na + b= 2^n 。那么 ff 就可以完整的表达整个 DNF :我们对 DNF 的 nn 个参数进行二进制编码,可以确定一个 [0,2n)[0, 2^n) 之间的数作为 aaff 根据输入的 aa 的即可返回答案。具体如何进行编码呢?我们让 xix_i 出现的 2i12^{i - 1} 次即可。举个例子,一个 DNF A(x1,x2,x3)=x1x2+x2x3A(x_1, x_2, x_3) = x_1 x_2 + x_2 x_3 ,我们构造的对应方式即为 B(x1,x2,x2,x3,x3,x3,x3)B(x_1, x_2, x_2, x_3, x_3, x_3, x_3) ,可以知道,一定存在一个 B 使得 B 能够表达出 A 。

nonsense

明天早上要去深圳。不能太坑队友了是不,所以可能暂时不会更新了 →_→