Codeforces Round #334 (Div. 1) C - Lieges of Legendre
题目大意:有n堆石子,每堆ai个,每次可以选择其中一堆拿掉一个,或者选一个数量为2 * x的堆将它变成k堆x个。
问你先手胜还是后手胜。
思路:显然要用sg函数,k为偶数的情况比较简单,看表可以直接得到答案,k为奇数的情况下需要求一下sg,
小数据需要特判一下。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int,int> #define piii pair<int, pair<int,int> > using namespace std; const int N = 2e5 + 10; const int M = 10 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-6; int n, k; int getSg(int x) { if(x == 0) return 0; if(!k) { if(x == 1) return 1; if(x == 2) return 2; if(x & 1) return 0; if(!(x & 1)) return 1; } else { if(x == 1 || x == 3) return 1; if(x & 1) return 0; int vis[3]; memset(vis, 0, sizeof(vis)); vis[getSg(x - 1)] = true; vis[getSg(x / 2)] = true; for(int i = 0; ; i++) if(!vis[i]) return i; } } int main() { scanf("%d%d", &n, &k); k = k & 1; int ans = 0; for(int i = 1; i <= n; i++) { int x; scanf("%d", &x); ans ^= getSg(x); } if(ans) puts("Kevin"); else puts("Nicky"); return 0; } /* */