← 全部文章 ARC091F Strange Nim 题解 2020 年 4 月 23 日 题解 更新于 2020 年 5 月 19 日
本文目录(3 节) 题意 题解 代码
ARC091F Strange Nim
题意
有 n n n 堆石子,第 i i i 堆有 a i a_i a i 个石子和一个整数 k i k_i k i 。
两个人轮流,每次选择一堆,从中要取出至少一个石子 。
设选择了第 i i i 堆,当前还剩下 x x x 个石子,则可以从中取出 [ 1 , ⌊ x k i ⌋ ] [1,\lfloor \frac{x}{k_i} \rfloor] [ 1 , ⌊ k i x ⌋] 个石子。
谁不能取了谁就输了,问最优策略下谁会获胜。
n ≤ 200 n \le 200 n ≤ 200 ,a i , k i ≤ 10 9 a_i,k_i \le 10^9 a i , k i ≤ 1 0 9 。
题解
显然考虑每一堆的 SG 函数,若所有 SG 值异或起来为 0 0 0 则后手赢,否则先手赢。
考虑如何计算 SG 函数,可以发现在 k k k 意义下的 SG 函数 s g ( n ) sg(n) s g ( n ) 的值为:
s g ( n ) = { n k k ∣ n s g ( n − ⌊ n k ⌋ − 1 ) k ∤ n
sg(n) =\begin{cases}\frac nk & k \mid n \\\\sg(n - \lfloor \frac nk \rfloor - 1) & k \nmid n\end{cases}
s g ( n ) = ⎩ ⎨ ⎧ k n s g ( n − ⌊ k n ⌋ − 1 ) k ∣ n k ∤ n
考虑根号分治计算 s g ( n ) sg(n) s g ( n ) ,设 w = max i = 1 n a i w = \max_{i=1}^n a_i w = max i = 1 n a i 。
若 ⌊ n k ⌋ ≥ w \lfloor \frac nk \rfloor \ge \sqrt w ⌊ k n ⌋ ≥ w ,则直接转化为求 g ( n − ⌊ n k ⌋ − 1 ) g(n - \lfloor \frac nk \rfloor - 1) g ( n − ⌊ k n ⌋ − 1 ) ,每次 n n n 至少减少 w \sqrt w w ,至多执行 O ( w ) \mathcal O(\sqrt w) O ( w ) 次。
否则,一次性将 n n n 减若干个 ⌊ n k ⌋ + 1 \lfloor \frac nk \rfloor + 1 ⌊ k n ⌋ + 1 ,直到 ⌊ n k ⌋ \lfloor \frac nk \rfloor ⌊ k n ⌋ 改变或者 k ∣ n k \mid n k ∣ n ,每次 ⌊ n k ⌋ \lfloor \frac nk \rfloor ⌊ k n ⌋ 减少 1 1 1 ,至多执行 O ( w ) \mathcal O(\sqrt w) O ( w ) 次。
总时间复杂度 O ( n w ) \mathcal O(n \sqrt w) O ( n w ) 。
实现时不用分治,直接写就可以了。
代码
inline int SG(int n, int k) {
int x = n / k, y = n % k;
return y ? SG(n - (y + x) / (x + 1) * (x + 1), k) : x;
}
int main() {
int n, w, k, ans = 0;
rd(n);
while (n--) rd(w, k), ans ^= SG(w, k);
prints(ans ? "Takahashi" : "Aoki");
return 0;
}
标签:博弈论 、根号分治
较新一篇 Codeforces Round #637 (Div. 1) – Thanks, Ivan Belonogov! 题解较早一篇 ARC096E Everything on It 题解返回全部文章
评论
暂无已公开评论。