您的位置:首页 > 其它

Codeforces-15C Industrial Nim

2013-11-04 20:04 218 查看
题意:有n个沙场,每个沙场有m个车子,每个车子里装的石子个是从第一车子里依次递增的。他们两相互取石子,问是先取赢还是后取赢。

这题是裸的Nim游戏,ans=s1^s2......s3.s代表每一堆石子的个数。

这题最主要不在于Nim游戏的结论,而是怎样在连续的自然数中快速求出前m个数的异或,这是基于一些理论:【(N^0=N),(1^1=0,1^0=1,0^0=0),(N^(N+1)=1,N为偶数),异或满足交换律】,结合数学分类可以快速求出。

#include<iostream>
#include<cstdio>
#include<cstring>
typedef __int64 LL;
using namespace std ;

LL get(LL x,LL y)                   //基于n^(n+1)=1,n为偶数。
{
LL ans;
if(y&1){                     //有奇数个
if(x&1) ans=x;       //取x后面的数。
else ans=x+y-1;      //取x+y-1前面的数。
y--;
}
else{
if(x&1) ans=x^(x+y-1),y-=2;         //可以求出中间的,取两头。
else ans=0;
}
return y%4==0? ans:ans^1;                  //判断是否为偶数对
}

int main()
{
int n;
LL x,m,ans=0;
scanf("%d",&n);
while(n--){
scanf("%I64d %I64d",&x,&m);
ans^=get(x,m);
}
printf(ans?"tolik\n":"bolik\n");
return 0 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数学 思维训练