← 全部文章

ARC091F Strange Nim 题解

本文目录(3 节)
  1. 题意
  2. 题解
  3. 代码

ARC091F Strange Nim

题意

  • 有 nn 堆石子,第 ii 堆有 aia_i 个石子和一个整数 kik_i。
  • 两个人轮流,每次选择一堆,从中要取出至少一个石子。
  • 设选择了第 ii 堆,当前还剩下 xx 个石子,则可以从中取出 [1,⌊xki⌋][1,\lfloor \frac{x}{k_i} \rfloor] 个石子。
  • 谁不能取了谁就输了,问最优策略下谁会获胜。
  • n≤200n \le 200,ai,ki≤109a_i,k_i \le 10^9。

题解

显然考虑每一堆的 SG 函数,若所有 SG 值异或起来为 00 则后手赢,否则先手赢。

考虑如何计算 SG 函数,可以发现在 kk 意义下的 SG 函数 sg(n)sg(n) 的值为: sg(n)={nkk∣nsg(n−⌊nk⌋−1)k∤n sg(n) =\begin{cases}\frac nk & k \mid n \\\\sg(n - \lfloor \frac nk \rfloor - 1) & k \nmid n\end{cases} 考虑根号分治计算 sg(n)sg(n),设 w=max⁡i=1naiw = \max_{i=1}^n a_i。

若 ⌊nk⌋≥w\lfloor \frac nk \rfloor \ge \sqrt w,则直接转化为求 g(n−⌊nk⌋−1)g(n - \lfloor \frac nk \rfloor - 1),每次 nn 至少减少 w\sqrt w,至多执行 O(w)\mathcal O(\sqrt w) 次。

否则,一次性将 nn 减若干个 ⌊nk⌋+1\lfloor \frac nk \rfloor + 1,直到 ⌊nk⌋\lfloor \frac nk \rfloor 改变或者 k∣nk \mid n,每次 ⌊nk⌋\lfloor \frac nk \rfloor 减少 11,至多执行 O(w)\mathcal O(\sqrt w) 次。

总时间复杂度 O(nw)\mathcal O(n \sqrt 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;
}

标签:博弈论、根号分治

评论

    填写昵称即可留言。评论经站主审核后公开,请勿提交私人信息。

    正在连接评论服务…