agc091F - Strange Nim

题目大意

题解

大概找了几分钟的规律

把表打出来,发现当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\n":"Aoki\n");
	
	fclose(stdin);
	fclose(stdout);
	return 0;
}
posted @ 2020-09-27 21:26  gmh77  阅读(145)  评论(0)    收藏  举报