codeforces 15C Industrial Nim(NIM 博弈)

题目链接: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

<p< p="">

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

<p< p="">tolik

Sample Input

Input
2
2 1
3 2
Output
tolik
Input
4
1 1
1 1
1 1
1 1
Output
bolik
题目大意:给定你n个序列 每个序列的第一个元素为x  一个序列有m个元素 这个序列的公差为1;

每次从所有的元素 中取>=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;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值