您的位置:首页 > 其它

codeforces 768E Game of Stones

2017-02-21 11:32 411 查看
题目链接:http://codeforces.com/problemset/problem/768/E

NIM游戏改版:对于任意一堆,拿掉某个次数最多只能一次。

对于一堆石头数量为$X$。找到一个最小的$Z$使得${ (\sum_{i=1}^{Z}i)\leq x}$,我们把这一堆数量为X的石头,看作Z个数目分别为${1...n}$的石头堆。

那么一次拿一定量的石头,是不是相当于拿走了${{1,2,3....,Z}}$中的任意多堆石头?

当然如果拿的石头数目$P$超过了${\sum _{i=1}^{Z}i}$,相当于拿走了所有大于${{Z}'}$的的石头堆。${{Z}'=Max\left \{ val|(\sum _{i=1}^{val}i)\leq (X-P) \right \}}$

所以${SG(X)=Max(Z|(\sum_{i=1}^{Z}i)\leq X)}$

很显然,这是一个multi-nim游戏,主游戏的SG值等于所有子游戏的异或和。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<cmath>
#include<cstring>
using namespace std;
#define maxn 10010
#define llg long long
#define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
llg n,m,x,v;

llg make_sg(llg x)
{
if (x==0) return 0;
llg l=0,r=(llg)1e9,val;
while (l<=r)
{
llg mid=(l+r)>>1;
if ((mid*mid+mid)/2<=x) {l=mid+1; val=mid;}else r=mid-1;
}
return val;
}

int main()
{
yyj("SG");
cin>>n;

for (llg i=1;i<=n;i++)
{
scanf("%lld",&v);
x^=make_sg(v);
}
if (!x) cout<<"YES";else cout<<"NO";
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: