bzoj4035: [HAOI2015]T3

發現翻轉相當於增加一個白格
對於一個白格子,它的SG值只與它還能跳的次數有關,如長度10,SG[4]=SG[5]。於是不同的狀態只有sqrt(n)個。只要求出還能跳k步的位置的SG就能得到答案。
暴力DP即可,貌似O(n)能過
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define N 100005
using namespace std;
int n,k,sg[N],sg1[N],f[N],x,Ans;
int nxt(int x,int y){return (x==y)?y+1:y/(y/(x+1));}
int main()
{
	scanf("%d%d",&n,&k);int sqn=sqrt(n);
	//memset(sg,-1,sizeof sg);
	//memset(sg1,-1,sizeof sg1);
	for (int i=1,now;i<=n;i=nxt(i,n))
	{
		now=0;
		for (int j=2;j<=i;j=nxt(j,i))
		{
			int t=i/j,p=(t<=sqn)?sg[t]:sg1[n/t];
			f[now^p]=i;
			if ((i/t-i/(t+1))&1) now^=p;
		}
		now=1;
		while (f[now]==i) now++;
		if (i<=sqn) sg[i]=now;
		else sg1[n/i]=now;
	}
	while(k--)
	{
		Ans=0;int m;
		scanf("%d",&m);
		for (int i=1,t;i<=m;i++)
			scanf("%d",&x),t=n/x,
				Ans^=(t<=sqn)?sg[t]:sg1[n/t];
		puts(Ans?"Yes":"No");
	}
}


發佈了93 篇原創文章 · 獲贊 24 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章