zoj 3591 Nim

Nim


Time Limit: 3 Seconds      Memory Limit: 65536 KB


Nim is a mathematical game of strategy in which two players take turns removing objects from distinct heaps. The game ends when one of the players is unable to remove object in his/her turn. This player will then lose. 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. Here is another version of Nim game. There are N piles of stones on the table. Alice first chooses some CONSECUTIVE piles of stones to play the Nim game with Tom. Also, Alice will make the first move. Alice wants to know how many ways of choosing can make her win the game if both players play optimally.

You are given a sequence a[0],a[1], ... a[N-1] of positive integers to indicate the number of stones in each pile. The sequence a[0]...a[N-1] of length N is generated by the following code:

int g = S;

for (int i=0; i<N; i++) {

a[i] = g;

if( a[i] == 0 ) { a[i] = g = W; }

if( g%2 == 0 ) { g = (g/2); }

else           { g = (g/2) ^ W; }

}

Input

There are multiple test cases. The first line of input is an integer T(T ≤ 100) indicates the number of test cases. Then T test cases follow. Each test case is represented by a line containing 3 integers NS and W, separated by spaces. (0 < N ≤ 105, 0 < S, W ≤ 109)

Output

For each test case, output the number of ways to win the game.

Sample Input

2
3 1 1
3 2 1

Sample Output

4
5


Author: CAO, Peng
Contest: The 12th Zhejiang University Programming Contest

 

题意:有n堆火柴,选择连续的火柴堆进行Nim游戏,问先手获胜有多少种方案。

分析:如果是普通的Nim游戏,那么就是对每个火柴堆取异或,如果先手要赢,那么异或的值就要非0。那么题目就变成在N个火柴堆里面有多少个连续火柴堆异或值非0。一开始的思路是最简单粗暴的枚举区间,但是N^2的复杂度显然是过不了的,所以这里用a[i]保存从第一个数到第i个数的异或值,那么第i到j堆的异或值为a[j]^a[i-1],由于非零情况多不好求,于是取对立情况即两个相等的数异或为0那么先手就会输,题目就变成了有多少个a[i]相等,就相当于是求出了原数组里面是有多少个连续的区间。做法是排序之后扫一遍看有多少个相等。1~n的连续区间个数是n*(n+1)/2,如果有x个相同的值的话,减去x*(x-1)/2即可,注意0要另外减去0的个数,因为0代表1~x这个区间先手必败。

注意答案要用long long

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<stdlib.h>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
#define LL long long
using namespace std;
const int MAXN=100000+5;
int kase,N,S,W,d;
int vv[MAXN],a[MAXN];

int main()
{
    scanf("%d",&kase);
    while(kase--)
    {
        scanf("%d %d %d",&N,&S,&W);
        memset(vv,0,sizeof(vv));
        memset(a,0,sizeof(a));

        int g=S,d=0;
        for (int i=0; i<N; i++)
        {
            a[i]= g;
            if( a[i] == 0 ) { a[i] = g = W; }
            if( g%2 == 0 ) { g = (g/2); }
            else { g = (g/2) ^ W; }
            d^=a[i];
            vv[i]=d;
        }
        sort(vv,vv+N);
        LL sum=(LL)N*((LL)N+1)/2;
        LL len=1;
        for(int i=1;i<N;i++)
        {
            if(vv[i]==vv[i-1])
                len++;
            else
            {
                if(vv[i-1]==0)
                    sum-=len;
                sum-=(len-1)*len/2;
                len=1;
            }
        }
        sum-=(len-1)*len/2;
        printf("%lld\n",sum);
    }
    return 0;
}

时间: 2024-10-13 03:10:39

zoj 3591 Nim的相关文章

ZOJ 3591 Nim (连续子序列异或和)

题目链接:ZOJ 3591 Nim 题意:根据题目给出的代码得到n堆石头的各自的数量,求先手选出连续的若干堆并且必胜的方法数.(比如:3,1,1 每堆石头数是1,1,1.先手选出(1),(1),(1),(1,1,1) 这四种方案是必胜的,所以答案是4) 思路:在n堆取石头首先想到的是Nim博弈,连续的若干堆,即求连续子序列异或和为0的数量m,n*(n+1)/2-m就是答案 (Nim博弈结论,a1,a2,a3--an,an-1,若a1^a2^a3^--^an^an-1=0先手必败 ) 连续子序列异

ZOJ 3591 Nim 前缀和+位运算

Nim Time Limit: 3 Seconds      Memory Limit: 65536 KB Nim is a mathematical game of strategy in which two players take turns removing objects from distinct heaps. The game ends when one of the players is unable to remove object in his/her turn. This

Zoj 3591 Nim 【博弈】【搜索】

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3591 题目大意:给你T组case,每组case有N,S,W三个数字,根据题目给出的代码可以算出每组石子个数a[i]. 已知了N组石子的个数,现在让你来选出连续的石子堆,使得先手会赢,问有多少种选法. 比如给出的样例:NSW分别是 3 1 1 则算出来的每堆石子的个数a[i]是 1 1 1,则 1 1 1三堆石子的选法有: 选第一堆,选第二堆,选第三堆,选第一堆到

zoj3591 Nim(Nim博弈)

ZOJ 3591 Nim(Nim博弈) 题目意思是说有n堆石子,Alice只能从中选出连续的几堆来玩Nim博弈,现在问Alice想要获胜有多少种方法(即有多少种选择方式). 方法是这样的,由于Nim博弈必胜的条件是所有数的抑或值不为0,证明见  点击  ,所以答案就转化为原序列有多少个区间的亦或值为0,用n*(n+1) / 2 减去这个值就可以了. 而求有多少个区间的亦或值为0,实际上就是求对于亦或值的前缀nim[i],满足nim[i] == nim[j] 的对数,这时只要对nim数组排序就可以

[博弈]ZOJ3591 Nim

题意: 给了一串数,个数不超过1e5,这串数是通过题目给的一段代码来生成的 int g = S; for (int i=0; i<N; i++) { a[i] = g; if( a[i] == 0 ) { a[i] = g = W; } if( g%2 == 0 ) { g = (g/2); } else { g = (g/2) ^ W; } } 其中S.N.W都是输入的. 问:从中取连续的一段出来玩Nim博弈,先手赢的取法有多少种. Nim博弈的结论:每堆异或,最后结果为0的先手输,否则,先手

ZOJ 3529 A Game Between Alice and Bob (分解质因数+Nim博弈)

A Game Between Alice and Bob Time Limit: 5 Seconds      Memory Limit: 262144 KB Alice and Bob play the following game. A series of numbers is written on the blackboard. Alice and Bob take turns choosing one of the numbers, and replace it with one of

ZOJ 3964 Yet Another Game of Stones Nim游戏变种

ZOJ3964 解题思路 此题的题意比较容易理解,可以简单的看着 Nim 博弈的变种.但问题在于 Alice 对第 i 堆石子的取法必须根据 bi 确定.所以如果这个问题能够归结到正常的 Nim 博弈(取石子问题),则很容易解决. 考虑特判存在 bi=1 或 bi=2 的情况: 如果存在第 i 堆石子,其 ai 为奇数且 bi=2 ,则 Bob 必胜(Alice 在最优策略下无法取完该堆,但 Bob 可以). 如果存在 2 个及以上 bi=2 或 bi=1 且 ai>1 的情况,则 Bob 必胜

BZOJ 3105: [cqoi2013]新Nim游戏

3105: [cqoi2013]新Nim游戏 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1064  Solved: 624[Submit][Status][Discuss] Description 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴.可以只拿一根,也可以拿走整堆火柴,但不能同时从超过一堆火柴中拿.拿走最后一根火柴的游戏者胜利. 本题的游

概率dp ZOJ 3640

Help Me Escape Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit Status Practice ZOJ 3640 Appoint description:  System Crawler  (2014-10-22) Description Background     If thou doest well, shalt thou not be accepted? an