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=2k⋅s ,其中 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
xi⊕xi′ 一定可以用
[
i
+
1
,
N
]
[i+1, N]
[i+1,N] 行的向量拼出来。
- 举个例子,考虑:
11110000
和它的循环移位01111000
,它们异或之后的结果为10001000
,恰好是矩阵下一行。
- 举个例子,考虑:
读者不难证明自行以上两个性质。通过这两个性质我们可以马上得到一个答案的下界:对于给定的 01 串,我们可以用线性基的知识找到它是哪几行拼出来的。假设最高的一行为第 i i i 行,那么答案为 N − i + 1 N-i+1 N−i+1 :先手输入第 i i i 行的向量,无论后手如何应对,这一轮结束之后第 i i i 行从 01 串的线性表示中消失,并且只会引入更低行的新向量。重复这个过程即可。
容易证明 N − i + 1 N-i+1 N−i+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=0∑nfk(⌊ki⌋)
要凑出
k
n
kn
kn,我们枚举面值 1 用了
k
(
n
−
i
)
k(n-i)
k(n−i) 个,那么剩下要凑的是
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,因为允许在本地跑,复杂度可以高一点。