前几天做过一道题目,是Nim游戏的一个扩展,也不能说扩展吧,只是说另一种常见的状态。
问题引入:
给定n堆石子,每堆石子有vi(1<=vi<=1e5) 个,每次可以取一堆中的一些石子,使得剩下的石子为1到vi/k个,为最后的是先手胜,还是后手胜,如果先手胜则输出相应的操作策略。
思考:
当k==2的时候,显然就退化成了la 5059 的题目,我们以此为基础来考虑,肯定要先计算出sg的函数表,然后观察规律,lrj在训练指南中说的很清楚,打表的规则也很简单,下面给出lrj所打出的表:
0 1 0 2 1 3 0 4 2 5
当然,lrj是从奇偶性来分析的,那么很容易得出
sg(x)=n%2==0?sg(n/2)这样的结论,因为k==2,刚好有一些特性被提现出来了。所以:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll sg(ll n)
{
return n%2==0 ? n/2 : sg(n/2);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
ll x;
scanf("%d",&n);
ll ans=0;