【UOJ#51】【UR #4】元旦三侠的游戏(博弈论)
题面
题解
考虑暴力,(sg[a][b])记录(sg)函数值,显然可以从(sg[a+1][b])和(sg[a][b+1])推过来。
发现可以从(sg[a][b])推到(sg[a][b+1])的值很少,所以可以直接把这些值全部提前计算出来,这部分大概有(sqrt n)个,剩下的可以推到(sg[a+1][b])而不能推到(sg[a][b+1])的位置可以通过(a)以及最大的满足(x^ble n)的(x)直接计算出来。
#include<iostream>
#include<cstdio>
#include<cmath>
int n,m,a,b,B[35];
bool f[35000][35],vis[35000][35];
int calc(int a,int b)
{
if(a>B[b])return true;
if(a>B[b+1])return (B[b]-a)&1;
if(vis[a][b])return f[a][b];
vis[a][b]=true;
if(!calc(a+1,b))return f[a][b]=true;
if(!calc(a,b+1))return f[a][b]=true;
return f[a][b]=false;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=32;++i)B[i]=floor(pow(n,1.0/i)+1e-9);
while(m--)
{
scanf("%d%d",&a,&b);
puts(calc(a,b)?"Yes":"No");
}
return 0;
}