H - Nim or not Nim? HDU - 3032

【题目意思】:
如图。
【思路】:
第一次遇到哈,学习一手。 博弈论进阶之Multi-SG - 自为风月马前卒 - 博客园 (cnblogs.com)
Multi-Nim 型题目。
它的定义是这样的:有nn堆石子,两个人可以从任意一堆石子中拿任意多个石子(不能不拿)或把一堆数量不少于2颗石子分为两堆不为空的石子堆,没法拿的人失败。问谁会胜利。
第一个操作从堆中拿出石子是常见的nim游戏。
第二个操作 将堆分成两堆 , 其实是变成两次nim游戏 。
根据 sg 的 原理 ,我们可以把分成的两次游戏看成当前游戏的一次后继 , 所以 当前游戏的sg(x) = sg(0,1,2,3,。。。,x-1,sg(y1,y2),sg(y3,y4)......)。
例子 :
如果当前的x等于5
sg[5] = mex( sg[0] , sg[1] , sg[2] ,sg[3] , sg[4] , sg({1,4}) , sg({2,3}) ) .
sg({2,3}) = sg(2)^sg(3) ;
另外这种游戏还有一个非常神奇的性质
x-1 ( x%4 ==0 )
x+1 ( x%4 == 3 )
然后把这个结论背过就好啦233
根据上面的游戏,我们定义Multi-SG游戏
-
- Multi-SG 游戏规定,在符合拓扑原则的前提下,一个单一游戏的
后继可以为多个单一游戏。 - Multi-SG其他规则与SG游戏相同。
- Multi-SG 游戏规定,在符合拓扑原则的前提下,一个单一游戏的
注意在这里要分清楚后继与多个单一游戏
对于一个状态来说,不同的划分方法会产生多个不同的后继,而在一个后继中可能含有多个独立的游戏
一个后继状态的SG值即为后继状态中独立游戏的异或和
该状态的SG值即为后继状态的SG值中未出现过的最小值
【代码】:
#include <bits/stdc++.h> #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <vector> #include <stack> #include <bitset> #include <cstdlib> #include <cmath> #include <set> #define ms(a, b) memset(a,b,sizeof(a)) #define fast ios::sync_with_stdio(false); cin.tie(0); cout.tie(0) #define ll long long #define ull unsigned long long #define rep(i, a, b) for(ll i=a;i<=b;i++) #define lep(i, a, b) for(ll i=a;i>=b;i--) #define endl '\n' #define pii pair<int, int> #define pll pair<ll, ll> #define vi vector<ll> #define vpi vector<pii> #define vpl vector<pll> #define mi map<ll,ll> #define all(a) (a).begin(),(a).end() #define gcd __gcd #define pb push_back #define mp make_pair #define lb lower_bound #define ub upper_bound #define ff first #define ss second #define test4(x, y, z, a) cout<<"x is "<<x<<" y is "<<y<<" z is "<<z<<" a is "<<a<<endl; #define test3(x, y, z) cout<<"x is "<<x<<" y is "<<y<<" z is "<<z<<endl; #define test2(x, y) cout<<"x is "<<x<<" y is "<<y<<endl; #define test1(x) cout<<"x is "<<x<<endl; using namespace std; const int N = 1e5 + 10; const int maxx = 0x3f3f3f; const int mod = 1e9 + 7; const int minn = -0x3f3f3f; const int M = 2 * N; ll T, n, m; ll a[N]; int sg(int x ){ if ( x%4==0 ) return x-1 ; if ( x%4==3 ) return x+1 ; return x; } void solve() { cin>>n; int res = 0 ; rep(i,1,n){ cin>> a[i] ; res ^= sg(a[i]); } if ( res ) cout<<"Alice"<<endl; else cout<<"Bob"<<endl; } int main() { fast; cin >> T; while (T--) { solve(); } return 0; }

浙公网安备 33010602011771号