题面:
A 和 B 在玩取石子游戏,他们轮流操作,每次选择其中一堆石子,取走一部分
有 n 堆石子,每堆一开始有 Ai 个
每堆石子在不同时刻能取的石头个数是不一样的
具体来说,当第 i 堆石子有 x 个的时候,最多在这堆石子中取走
⌊xKi⌋
⌊
x
K
i
⌋
个,
最少取走一个
1<=n<=200
1 <= Ai, Ki <= 1e9
题解:
写写画画发现K=4时,SG函数如下:
0 0 0 0
1 0 1 0
2 1 0 2
3 1 0 2
……
规律大概是去掉第一行后,从左到右,从上到下的序列都是一样的:
0 0 0 0 1 0 1 0 2 1 0 2……
所以有递推公式:
f(x,y)=f(x−(⌊xy⌋+1),y)
f
(
x
,
y
)
=
f
(
x
−
(
⌊
x
y
⌋
+
1
)
,
y
)
,注意到
⌊xKi⌋
⌊
x
K
i
⌋
在连续一段是一定的,因此可以类比整数分块的思想。
代码
#include <bits/stdc++.h>
using namespace std;
int solve(int x,int y)
{
if (x%y==0) return x/y;
int k=x/y+1;
return solve(x-max(1,x%y/k)*k,y);
}
int n,x,y,ans;
int main()
{
scanf("%d",&n);
while (n--)
{
scanf("%d%d",&x,&y),ans^=solve(x,y);
}
return printf("%s",ans?"Takahashi":"Aoki"),0;
}