[HDU5996]dingyeye loves stones

题目

点这里看题目。

分析

不难想到,这个问题实际上可以按照深度来划分(根的深度为 0),于是这就是一个阶梯 Nim 的问题。

阶梯 Nim 相当经典,它的模型是:

(n) 堆石子,编号为 (1sim n),第 (i) 堆有 (a_i) 个石子( (a_i>0) )。每一轮玩家可以选择任意非空的一堆 (k) ,并且可以移动任意多且不为零的石子至 (k-1) 堆(移动第 1 堆的石子相当于直接丢掉它们)。请问先手是否必胜?

问题的结论是:

阶梯 Nim 等价于对奇数堆的石子做 Nim 游戏。

考虑这样的过程:

  1. 如果对手移动奇数堆的石子,我们就按照 Nim 的策略来移动。这样每次操作后,奇数堆的石子会移动到偶数堆里面,奇数堆就是正常的 Nim 过程。
  2. 如果对手不按常理出牌,移动了偶数堆(第 (2n) 堆)的 (k) 个石子。那么我们就可以在 (2n-1) 堆里面,移动恰好 (k) 个石子至第 (2n-2) 堆。最后,要么这 (k) 个石子被丢掉,要么 (k) 个石子移动到偶数堆里,这样奇数堆的石子照样不会被影响。

这就是阶梯 Nim 的解决方案。实际上,这个结论是告诉我们,阶梯 Nim 的 SG 和是各个奇数位置的堆的异或和

回到原题。我们认为根的深度是 0 ,看做是 "垃圾桶" (也就是石子丢弃的位置)。对于同一深度上石子堆,移动它们的过程就相当于 Nim 的过程,于是某一深度的 SG 值就是该层上的石子的异或和;对于不同的深度,我们可以将它们看成是阶梯 Nim 的问题,于是整个游戏的 SG 值就是奇数深度的 SG 值的异或值。

代码:

#include <cstdio>

const int MAXN = 1e5 + 5;

template<typename _T>
void read( _T &x )
{
    x = 0;char s = getchar();int f = 1;
    while( s > '9' || s < '0' ){if( s == '-' ) f = -1; s = getchar();}
    while( s >= '0' && s <= '9' ){x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar();}
    x *= f;
}

template<typename _T>
void write( _T x )
{
    if( x < 0 ){ putchar( '-' ); x = ( ~ x ) + 1; }
    if( 9 < x ){ write( x / 10 ); }
    putchar( x % 10 + '0' );
}

struct Edge
{
    int to, nxt;
}Graph[MAXN << 1];

int dep[MAXN];
int head[MAXN], num[MAXN];
int N, cnt, Nim;

void AddEdge( const int from, const int to )
{
    Graph[++ cnt].to = to, Graph[cnt].nxt = head[from];
    head[from] = cnt;
}

void DFS( const int u, const int fa )
{
    if( ( dep[u] = dep[fa] + 1 ) % 2 == 0 ) Nim ^= num[u];
    for( int i = head[u] ; i ; i = Graph[i].nxt )
        DFS( Graph[i].to, u );
}

void Clean()
{
    Nim = cnt = 0;
    for( int i = 0 ; i <= N ; i ++ )
        head[i] = dep[i] = num[i] = 0;
}

int main()
{
    int T;
    read( T );
    while( T -- )
    {
        read( N ), Clean();
        for( int i = 1, fa ; i < N ; i ++ ) read( fa ), AddEdge( fa, i );
        for( int i = 0 ; i < N ; i ++ ) read( num[i] );
        DFS( 0, 0 );
        
        puts( Nim ? "win" : "lose" );
    }
    return 0;
}
原文地址:https://www.cnblogs.com/crashed/p/13746175.html