Nim Game(博弈)

题目描述

Nim is a mathematical game of strategy in which two players take turns removing objects from distinct heaps. On each turn, a player must remove at least one object, and may remove any number of objects provided they all come from the same heap |Fṝõṃ Wìǩìqèḋìa«țȟè ḟṝèè èñćẏćḽõqèḋìa¦. The goal of the game is to avoid being the player who doesn’t have any object to remove. The player who remove the last project is the winner.
Now KK and TT are playing Nim game with the optimal strategy. There are n heaps of stones. The number of stones in i‑th heap is ai. They play this game m times, and KK is the player making the first move. During the i‑th time they play the game on the heaps whose index in interval [li , ri]. KK wants to know whether he has a winning strategy or not.

输入

The input consists of several test cases. The first line of the input gives the number of test cases,T(1 ≤ T ≤ 103).
For test case, the first line contains two integers n(1 ≤ n ≤ 106 ) and m(1 ≤ m ≤ 106), representing the number of heap of stones and the game times.
The second line contains n positive integers a1, a2, ⋯ , an (1 ≤ ai ≤ 109), representing The number of stones in i‑th heap.
In the next m lines, each line contains two integers li, ri , which means the $i: KaTeX parse error: $ within math mode$th game is played on the interval[li , ri].
It’s guaranteed that ∑ n ≤ 2 × 10and  ∑ m ≤ 2 × 106

输出

For each test case, let fi represents the answer of the i-th game.
If KK has a winning strategy in the i-th game then fi=1, otherwise fi=0. Please output ∑ fi ∗ 2m-i mod 109 + 7,in which 1 ≤ i ≤ m
 

样例输入 Copy

3
2 1
1 1
1 2
2 1
1 2
1 2
3 2
1 2 2
1 2
2 3

样例输出 Copy

0
1
2

来源/分类

题意是给t组样例,每组n堆物品,m次博弈,问最后按题目要求计算出的和是多少。对二的次方先打表避免超时,

另外测试数据比较多,全部用scanf。

#include<iostream>
#include<map>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 1000010;
int a[N],b[N];
const int mod = 1e9 + 7;
int main(){
    b[0] = 1;
    for (int i = 1; i <= N; i++)  //打表二进制
        b[i] = b[i-1] * 2 % mod;
    int t;
    scanf("%d",&t);
    while (t--)
    {
        ll ans = 0;
        int n, m,sum=0,num;
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++)  //异或前缀和
            scanf("%d",&num), sum ^= num, a[i] = sum;
        while (m--)
        {
            int l, r;
            scanf("%d%d", &l, &r);
            int c = a[r] ^ a[l - 1];
            if (c !=0)   //判断能否赢
                ans = (ans + b[m]) % mod;
        }
        printf("%d\n", ans);
    }
    return 0;
}

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值