题目大意
题解
大概找了几分钟的规律
把表打出来,发现当n%k=0时SG为n/k,否则把%k≠0的部分拿出来,维护一个在原序列从0开始的指针跟着一起走,发现两个序列一样
按照题解的说法就是把%k=0的拿掉之后仍等于原序列,形式化就是sg[i]=sg[i-1-i/k]
证明考虑归纳,归纳发现n-n/k~n这一部分刚好取完了0~n/k,往后移的时候如果%k≠0就把去掉的哪一个赋过来,即sg[i]=sg[i-1-i/k],否则根据sg的定义会新开一个,即sg[i]=i/k
直接找会超时,所以每次跳到i/k的边界,时间大概是根号级别求一个
code
#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define ll long long
//#define file
using namespace std;
int n,m,i,j,k,l,x,y,ans;
int main()
{
#ifdef file
freopen("arc091D.in","r",stdin);
#endif
scanf("%d",&n);
fo(i,1,n)
{
scanf("%d%d",&x,&y);
while (x>=y && (x%y))
{
l=x/y;
x-=((x-(y*l))/(1+l))*(1+l);
if (x%y) x-=1+l;
}
ans^=x/y;
}
printf(ans?"Takahashi
":"Aoki
");
fclose(stdin);
fclose(stdout);
return 0;
}