题目大意
有n堆石子,每堆石子两个参数(A, K),每次取出[1, A/K]个石子,两个人轮流操作,不能取者输。求先手还是后手必胜。
解法
考虑SG函数sg(i)
sg(i) = i%k==0 ? i/k : sg(i-(i/k)-1)
考虑证明,可以用数学归纳法,对于每个位置,他前面(i-1)/k+1个位置包括了[0, (i-1)/k]。那么该位置要么为sg(i-(i/k)-1),要么为i/k。
代码
#include <cstdio>
using namespace std;
int f(int a, int k) {
if (a%k==0) return a/k;
else if (a%k>=a/k+1) return f(a-(a%k)/(a/k+1)*(a/k+1), k);
else return f(a-a/k-1, k);
}
int main() {
#ifdef DEBUG
freopen("src.in", "r", stdin);
freopen("src.out", "w", stdout);
#endif
int n, ans=0;
scanf("%d", &n);
for (int i=1; i<=n; i++) {
int a, k;
scanf("%d %d", &a, &k);
ans ^= f(a, k);
}
printf(ans ? "Takahashi
" : "Aoki
");
fclose(stdin);
fclose(stdout);
return 0;
}