模拟赛1sol

2月16日简要题解

light

这个题作为第一题是难了一点 = =。

下文中的“有解”表示“先手必胜”,首先说一个结论:

  • 如果 N = 2 k ​ N=2^k​ N=2k,那么对于任意的初始局面是有解的。
  • 否则,并不是每一种局面都是先手必胜的。

我们简单证明一下第二个结论,假设 N N N 是一个奇数,假设初始时存在相邻两个位置 ( x , x + 1 ) (x, x+1) (x,x+1) 的开关状态不一样。那么每次无论指定怎样的位置集合,总存在相邻两个位置同时被操作或者不被操作,我们让这两个位置作用到 ( x , x + 1 ) (x, x+1) (x,x+1) 上,那么它们的开关状态仍然保持不同。如果 N = 2 k ⋅ s N=2^k\cdot s N=2ks ,其中 s s s 是一个大于 1 的奇数时的证明类似。

因为我们保证输入有解,总可以把他归约到 2 k 2^k 2k 的情形,下面讨论 N = 2 k N=2^k N=2k 时候的情形。

我们递归地构造 01 矩阵:

  • N = 1 N=1 N=1 时候:
1
  • N = 2 N=2 N=2 时候:
1 0
1 1
  • N = 4 N=4 N=4 时候:
1 0 0 0
1 1 0 0
1 0 1 0
1 1 1 1
  • N = 8 N=8 N=8 时候:
1 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0
1 0 1 0 0 0 0 0
1 1 1 1 0 0 0 0
1 0 0 0 1 0 0 0
1 1 0 0 1 1 0 0
1 0 1 0 1 0 1 0
1 1 1 1 1 1 1 1

以此类推,读者很容易发现他的规律:对构造好的 N = 2 k N=2^k N=2k 的矩阵,把它复制 3 份放在左上、左下和右下,右上角以 0 填充。

这个矩阵很有特点,它有两个很关键的性质:

  • 把每一行视为一个 01 向量,那么它是一个线性基。
  • x i x_i xi 表示第 i 行的向量,令 x i ′ x'_i xi 表示将 x i x_i xi 循环移位若干位的向量,那么 x i ⊕ x i ′ x_i \oplus x'_i xixi 一定可以用 [ i + 1 , N ] [i+1, N] [i+1,N] 行的向量拼出来。
    • 举个例子,考虑:11110000 和它的循环移位 01111000,它们异或之后的结果为 10001000,恰好是矩阵下一行。

读者不难证明自行以上两个性质。通过这两个性质我们可以马上得到一个答案的下界:对于给定的 01 串,我们可以用线性基的知识找到它是哪几行拼出来的。假设最高的一行为第 i i i 行,那么答案为 N − i + 1 N-i+1 Ni+1 :先手输入第 i i i 行的向量,无论后手如何应对,这一轮结束之后第 i i i 行从 01 串的线性表示中消失,并且只会引入更低行的新向量。重复这个过程即可。

容易证明 N − i + 1 N-i+1 Ni+1 也是答案的上界,从而就是答案,这一部分工作留给读者完成。

所以最后的算法即为模拟一下就好了,代码量符合第一题的标准。

count

看起来大家都会啊。。。你们互相交流一下吧 QwQ

calc

首先组合意义转化一下,对于给定的 k k k, f k ( n ) f_k(n) fk(n) 表示这样一个值:

  • 想象你有无限多个面值为 1 , k , k 2 , … , k x , … 1, k, k^2, \dots, k^x, \dots 1,k,k2,,kx, 的硬币,那么 f k ( n ) f_k(n) fk(n) 为本质不同的,用这些硬币凑出 k n kn kn 的方案数。

解释:考虑递归式:
f k ( n ) = ∑ i = 0 n f k ( ⌊ i k ⌋ ) f_k(n) = \sum_{i=0}^{n} f_k\left(\left\lfloor \frac{i}{k} \right\rfloor\right) fk(n)=i=0nfk(ki)
要凑出 k n kn kn,我们枚举面值 1 用了 k ( n − i ) k(n-i) k(ni) 个,那么剩下要凑的是 k i ki ki 且最小可用的面值是 k k k,这样相当于用 1 , k , k 2 , … 1, k, k^2,\dots 1,k,k2, 去凑 i i i ,这个方案数恰好为 f k ( [ i / k ] ) f_k([i/k]) fk([i/k])

问题的后一部分参见 BZOJ 4588,因为允许在本地跑,复杂度可以高一点。

你可能感兴趣的:(模拟赛)