题目链接:http://vjudge.net/contest/view.action?cid=47997#problem/C
Description
There are n stone quarries in Petrograd.
Each quarry owns mi dumpers (1 ≤ i ≤ n). It is known that the first dumper of the i-th quarry has xi stones in it, the second dumper hasxi + 1 stones in it, the third has xi + 2, and the mi-th dumper (the last for the i-th quarry) has xi + mi - 1 stones in it.
Two oligarchs play a well-known game Nim. Players take turns removing stones from dumpers. On each turn, a player can select any dumper and remove any non-zero amount of stones from it. The player who cannot take a stone loses.
Your task is to find out which oligarch will win, provided that both of them play optimally. The oligarchs asked you not to reveal their names. So, let's call the one who takes the first stone «tolik» and the other one «bolik».
Input
The first line of the input contains one integer number n (1 ≤ n ≤ 105) — the amount of quarries. Then there follow n lines, each of them contains two space-separated integers xi and mi (1 ≤ xi, mi ≤ 1016) — the amount of stones in the first dumper of the i-th quarry and the number of dumpers at the i-th quarry.
Output
Sample Input
2 2 1 3 2
tolik
4 1 1 1 1 1 1 1 1
bolik
每次从所有的元素 中取>=1的数 判断最后是先手赢还是后手赢;
由于元素个数较多 我们需要对其进行整理 不能简单的进行异或
异或有如下的运算法则 1^1=0 1^0=1 ,0^0=0 n^(n+1)=1(n为偶数的时候);
因此我们可以对一个序列进行一次处理
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;
LL get(LL x,LL m) //n^(n+1)=1(n为偶数) 1^1=0 0^0=0
{
LL ans;
if(m&1){
if(x&1)
ans=x;//后面的可以配成对
else
ans=x+m-1;//除去最后一项前面的可以配成对
m--;
}
else{
if(x&1){
ans=x^(x+m-1);//中间的可以配成对
m-=2;
}
else
ans=0;
}
if(m%4)//判断是否为偶数对
return ans^1;
else
return ans;
}
int main()
{
int n;
long long a,b;
while(~scanf("%d",&n)){
long long ans=0;
for(int i=0;i<n;i++){
scanf("%lld%lld",&a,&b);
ans^=get(a,b);
}
if(ans)
puts("tolik");
else
puts("bolik");
}
return 0;
}