bzoj 1228 [SDOI2009]E&D 博弈论
Posted copperoxide
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 1228 [SDOI2009]E&D 博弈论相关的知识,希望对你有一定的参考价值。
题面
解法
显然,这个游戏可以拆成多个游戏的和
那么,我们就可以使用SG定理
定义(SG(x,y))表示同一组石子中分别有(x)个石子和(y)个石子的(SG)值
发现(x,y≤10^9),然后打表找规律
可以发现,若(x,y)都为奇数,那么(SG(x,y)=0)
否则,(SG(x,y)=SG(lceilfrac{x}{2} ceil,lceilfrac{y}{2} ceil)+1)
那么求解SG值就变成(O(log x))了
代码
#include <bits/stdc++.h>
#define N 110
using namespace std;
template <typename node> void chkmax(node &x, node y) {x = max(x, y);}
template <typename node> void chkmin(node &x, node y) {x = min(x, y);}
template <typename node> void read(node &x) {
x = 0; int f = 1; char c = getchar();
while (!isdigit(c)) {if (c == ‘-‘) f = -1; c = getchar();}
while (isdigit(c)) x = x * 10 + c - ‘0‘, c = getchar(); x *= f;
}
int SG(int x, int y) {
if (x > y) swap(x, y);
if (x % 2 == 1 && y % 2 == 1) return 0;
return SG((x + 1) / 2, (y + 1) / 2) + 1;
}
int main() {
int T; read(T);
while (T--) {
int n, ans = 0; read(n);
for (int i = 1; i <= n / 2; i++) {
int x, y; read(x), read(y);
ans ^= SG(x, y);
}
if (ans) cout << "YES
";
else cout << "NO
";
}
return 0;
}
以上是关于bzoj 1228 [SDOI2009]E&D 博弈论的主要内容,如果未能解决你的问题,请参考以下文章