变量含义
sg [i][j] == k 表示i*j的矩形局面的SG函数为k
vis [i] == true 表示当前局面的存在SG函数值为i的后继局面
#include<bits/stdc++.h>
namespace OI
{
#define il inline
#define rg register
using std :: getchar;
using std :: min;
using std :: max;
bool rd ( int &k ){
char c = getchar (); while ( c != EOF && c != '-' && ( c < '0' || c > '9' ) ){ c = getchar (); }
if ( c == EOF ){ return false; } bool neg = false; if ( c == '-' ){ neg = true; k = 0; }else{ neg = false; k = c - '0'; }
c = getchar (); while ( c >= '0' && c <= '9' ){ k = (k<<1)+(k<<3)+c-'0'; c = getchar (); }
if ( neg ){ k = -k; } return true;
}
const int maxSide = 205;
int sg [maxSide][maxSide];
int sG ( int r, int c ){
if ( sg [r][c] != -1 ){ return sg [r][c]; } //记忆化
int vis [maxSide]; memset ( vis, 0, sizeof ( vis ) ); //建一个空集用于mex运算
for ( rg int i = 2; i <= r-i; ++i ){ vis [ sG ( i, c ) ^ sG ( r-i, c ) ] = true; }
//上一行:i不从1开始一是因为1*x和x*1局面必败,避免考虑以减小搜索规模;二是因为这样的写法会无限递归
//接上:以i<=r-i作为循环边界是因为在向后进行循环就和之前的求解重复了
//接上:SG(有向图游戏的和)=SG(第一个有向图游戏)^SG(第二个有向图游戏)^...^SG(最后一个有向图游戏)
for ( rg int i = 2; i <= c-i; ++i ){ vis [ sG ( r, i ) ^ sG ( r, c-i ) ] = true; }
sg [r][c] = 0; while ( vis [ sg [r][c] ] ){ sg [r][c] ++; }
//上一行:SG(当前局面)=mex({当前局面的后继局面的SG值})
return sg [c][r] = sg [r][c]; //r*c局面与c*r局面等价
}
void Main (){
memset ( sg, -1, sizeof ( sg ) );
sg [2][3] = sg [3][2] = sg [2][2] = 0; //转化终止状态以符合有向图游戏的要求“终止状态”为必败
int r, c; while ( rd ( r ) && rd ( c ) ){ if ( sG ( r, c ) > 0 ){ puts ("WIN"); }else{ puts ("LOSE"); } }
}
}
int main (){
OI::Main();
return 0;
}