题解/算法 {1319. 移棋子游戏}
LINK: https://www.acwing.com/problem/content/description/1321/
;
令
G
G
G为DAG图;
令
G
G
a
GG_a
GGa表示一个公平的子游戏 在
G
G
G在
a
a
a点上有一个棋子;
可知, 当前游戏 为
G
G
GG
GG的组合游戏 比如在a,b,c,d
上有一个棋子, 即当前游戏可以表示为{ GGa, GGb, GGc, GGd}
(每次选择一个子游戏 操作他的棋子, 该操作并不会影响其他子游戏的状态, 因此这是组合游戏);
子游戏的SG值:
.
终止态: 当棋子在叶子节点 (即无儿子);
int Get_SG( int _a){ // `a >= 0`;
static int __record[ 102];
{ static bool __is_first = true; if( __is_first){ __is_first = false; memset( __record, -1, sizeof( __record));}}
auto & ANS = __record[ _a];
if( ANS != -1){ return ANS;}
//--
{ // 检查终止态;
bool is_leaf = false;
if( G->Head[ _a] == -1){
is_leaf = true;
}
if( is_leaf){ return ANS = 0;}
}
unordered_set< int> mex;
for( int edge = G->Head[ _a]; ~edge; edge = G->Next[ edge]){
mex.insert( Get_SG( G->Vertex[ edge]));
}
//> 对`mex`进行MEX操作;
for( ANS = 0; ; ++ANS){
if( mex.find( ANS) == mex.end()){
break;
}
}
return ANS;
}